diff -Nru umbrello-4.12.3/CMakeLists.txt umbrello-4.12.90/CMakeLists.txt --- umbrello-4.12.3/CMakeLists.txt 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/CMakeLists.txt 2014-03-05 15:04:09.000000000 +0000 @@ -8,10 +8,10 @@ set(VERSION_MAJOR "2") set(VERSION_MINOR "12") -set(VERSION_PATCH "3") +set(VERSION_PATCH "99") # set default umbrello version -# umbrello version could be overriden by cmake command line using -DUMBRELLO_VERSION_STRING=major.minor.patch +# umbrello version could be overridden by cmake command line using -DUMBRELLO_VERSION_STRING=major.minor.patch if(NOT UMBRELLO_VERSION_STRING) set(UMBRELLO_VERSION_STRING "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}") if(EXISTS ${CMAKE_SOURCE_DIR}/.git) @@ -20,8 +20,10 @@ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} OUTPUT_VARIABLE _hash ) - string(REPLACE "\n" "" hash ${_hash}) - set(UMBRELLO_VERSION_STRING "${UMBRELLO_VERSION_STRING}-${hash}") + if(_hash) + string(REPLACE "\n" "" hash ${_hash}) + set(UMBRELLO_VERSION_STRING "${UMBRELLO_VERSION_STRING}-${hash}") + endif() endif() endif() @@ -42,10 +44,6 @@ macro_optional_find_package(LibXml2) macro_log_feature(LIBXML2_FOUND "LibXML2" "Libraries used to develop XML applications" "http://xmlsoft.org" FALSE "" "Required to build Umbrello.") -set(Boost_MINIMUM_VERSION 1.33.1) -macro_optional_find_package(Boost) -macro_log_feature(Boost_FOUND "boost" "Boost C++ Libraries" "http://www.boost.org" FALSE "1.33.1" "Required to build Umbrello.") - add_definitions (${QT_DEFINITIONS} ${KDE4_DEFINITIONS}) include_directories( ${KDE4_INCLUDES} @@ -55,7 +53,7 @@ KDE4_NO_ENABLE_FINAL(umbrello) -if(LIBXSLT_FOUND AND LIBXML2_FOUND AND Boost_FOUND) +if(LIBXSLT_FOUND AND LIBXML2_FOUND) add_subdirectory( umbrello ) add_subdirectory( doc ) # do we build the unit tests @@ -63,4 +61,4 @@ ENABLE_TESTING() add_subdirectory(unittests) endif(KDE4_BUILD_TESTS) -endif(LIBXSLT_FOUND AND LIBXML2_FOUND AND Boost_FOUND) +endif(LIBXSLT_FOUND AND LIBXML2_FOUND) diff -Nru umbrello-4.12.3/debian/changelog umbrello-4.12.90/debian/changelog --- umbrello-4.12.3/debian/changelog 2014-03-04 20:24:21.000000000 +0000 +++ umbrello-4.12.90/debian/changelog 2014-03-19 12:12:52.000000000 +0000 @@ -1,3 +1,9 @@ +umbrello (4:4.12.90-0ubuntu1) trusty; urgency=medium + + * New upstream beta release + + -- Jonathan Riddell Wed, 19 Mar 2014 12:12:50 +0000 + umbrello (4:4.12.3-0ubuntu1) trusty; urgency=medium * New upstream bugfix release diff -Nru umbrello-4.12.3/debian/control umbrello-4.12.90/debian/control --- umbrello-4.12.3/debian/control 2014-03-04 20:24:21.000000000 +0000 +++ umbrello-4.12.90/debian/control 2014-03-19 12:12:52.000000000 +0000 @@ -4,7 +4,7 @@ Maintainer: Kubuntu Developers Build-Depends: kde-sc-dev-latest (>= 4:4.10.2), cmake, debhelper (>= 9), pkg-kde-tools (>= 0.12), - kdelibs5-dev (>= 4:4.12.3), + kdelibs5-dev (>= 4:4.12.90), libxslt1-dev, libxml2-dev, libboost1.54-dev Standards-Version: 3.9.4 Homepage: http://www.kde.org diff -Nru umbrello-4.12.3/debian/umbrello.install umbrello-4.12.90/debian/umbrello.install --- umbrello-4.12.3/debian/umbrello.install 2014-03-04 20:24:21.000000000 +0000 +++ umbrello-4.12.90/debian/umbrello.install 2014-03-19 12:12:52.000000000 +0000 @@ -76,6 +76,7 @@ usr/share/kde4/apps/umbrello/icons/hicolor/22x22/actions/umbrello_diagram_state.png usr/share/kde4/apps/umbrello/icons/hicolor/22x22/actions/umbrello_diagram_usecase.png usr/share/kde4/apps/umbrello/layouts/activity-export.desktop +usr/share/kde4/apps/umbrello/layouts/activity-vertical.desktop usr/share/kde4/apps/umbrello/layouts/class-export.desktop usr/share/kde4/apps/umbrello/layouts/class-horizontal.desktop usr/share/kde4/apps/umbrello/layouts/class-vertical.desktop diff -Nru umbrello-4.12.3/doc/uml_basics.docbook umbrello-4.12.90/doc/uml_basics.docbook --- umbrello-4.12.3/doc/uml_basics.docbook 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/doc/uml_basics.docbook 2014-03-05 15:04:09.000000000 +0000 @@ -370,19 +370,19 @@ Class diagrams can contain several other items besides classes. Interfaces -Interfaces are abstract classes which means instances can not be directly created of them. They can contain operations but no attributes. Classes can inherit from interfaces (through a realisation association) and instances can then be made of these diagrams. +Interfaces are abstract classes which means instances cannot be directly created of them. They can contain operations but no attributes. Classes can inherit from interfaces (through a realisation association) and instances can then be made of these diagrams. Datatypes Datatypes are primitives which are typically built into a programming language. Common examples include integers and booleans. -They can not have relationships to classes but classes can have relationships to them. +They cannot have relationships to classes but classes can have relationships to them. Enums Enums are a simple list of values. A typical example is an enum for days of the week. The options of an enum are called Enum Literals. -Like datatypes they can not have relationships to classes but classes can have relationships to them. +Like datatypes they cannot have relationships to classes but classes can have relationships to them. diff -Nru umbrello-4.12.3/doc/xml/umbrello-diagrams.dtd umbrello-4.12.90/doc/xml/umbrello-diagrams.dtd --- umbrello-4.12.3/doc/xml/umbrello-diagrams.dtd 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/doc/xml/umbrello-diagrams.dtd 2014-03-05 15:04:09.000000000 +0000 @@ -1,14 +1,18 @@ + + + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include "ast.h" +#include +#include + +QString nodeTypeToString(int type) +{ + switch (type) { + case NodeType_Generic: + return "Generic"; + case NodeType_TemplateArgumentList: + return "TemplateArgumentList"; + case NodeType_ClassOrNamespaceName: + return "ClassOrNamespaceName"; + case NodeType_Name: + return "Name"; + case NodeType_Declaration: + return "Declaration"; + case NodeType_TypeSpecifier: + return "TypeSpecifier"; + case NodeType_BaseSpecifier: + return "BaseSpecifier"; + case NodeType_BaseClause: + return "BaseClause"; + case NodeType_ClassSpecifier: + return "ClassSpecifier"; + case NodeType_Enumerator: + return "Enumerator"; + case NodeType_EnumSpecifier: + return "EnumSpecifier"; + case NodeType_ElaboratedTypeSpecifier: + return "ElaboratedTypeSpecifier"; + case NodeType_LinkageBody: + return "LinkageBody"; + case NodeType_LinkageSpecification: + return "LinkageSpecification"; + case NodeType_Namespace: + return "Namespace"; + case NodeType_NamespaceAlias: + return "NamespaceAlias"; + case NodeType_Using: + return "Using"; + case NodeType_UsingDirective: + return "UsingDirective"; + case NodeType_InitDeclaratorList: + return "InitDeclaratorList"; + case NodeType_Typedef: + return "Typedef"; + case NodeType_Declarator: + return "Declarator"; + case NodeType_InitDeclarator: + return "InitDeclarator"; + case NodeType_TemplateDeclaration: + return "TemplateDeclaration"; + case NodeType_SimpleDeclaration: + return "SimpleDeclaration"; + case NodeType_Statement: + return "Statement"; + case NodeType_IfStatement: + return "IfStatement"; + case NodeType_WhileStatement: + return "WhileStatement"; + case NodeType_DoStatement: + return "DoStatement"; + case NodeType_ForStatement: + return "ForStatement"; + case NodeType_ForEachStatement: // qt4 [erbsland] + return "ForEachStatement"; + case NodeType_SwitchStatement: + return "SwitchStatement"; + case NodeType_CatchStatement: + return "CatchStatement"; + case NodeType_CatchStatementList: + return "CatchStatementList"; + case NodeType_TryBlockStatement: + return "TryBlockStatement"; + case NodeType_DeclarationStatement: + return "DeclarationStatement"; + case NodeType_StatementList: + return "StatementList"; + case NodeType_TranslationUnit: + return "TranslationUnit"; + case NodeType_FunctionDefinition: + return "FunctionDefinition"; + case NodeType_ExpressionStatement: + return "ExpressionStatement"; + case NodeType_ParameterDeclaration: + return "ParameterDeclaration"; + case NodeType_ParameterDeclarationList: + return "ParameterDeclarationList"; + case NodeType_ParameterDeclarationClause: + return "ParameterDeclarationClause"; + case NodeType_Group: + return "Group"; + case NodeType_AccessDeclaration: + return "AccessDeclaration"; + case NodeType_TypeParameter: + return "TypeParameter"; + case NodeType_TemplateParameter: + return "TemplateParameter"; + case NodeType_TemplateParameterList: + return "TemplateParameterList"; + case NodeType_Condition: + return "Condition"; + case NodeType_Custom: + return "Custom"; + } + + return QString(); +} + + +// ------------------------------------------------------------------------ +AST::AST() + : m_nodeType(NodeType_Generic), m_parent(0), + m_startLine(0), m_startColumn(0), + m_endLine(0), m_endColumn(0) +{ +} + +AST::~AST() +{ +#ifndef CPPPARSER_NO_CHILDREN + if (m_parent) + m_parent->removeChild(this); +#endif +} + +void AST::setStartPosition(int line, int col) +{ + m_startLine = line; + m_startColumn = col; +} + +void AST::getStartPosition(int* line, int* col) const +{ + if (line) + *line = m_startLine; + + if (col) + * col = m_startColumn; +} + +void AST::setEndPosition(int line, int col) +{ + m_endLine = line; + m_endColumn = col; +} + +void AST::getEndPosition(int* line, int* col) const +{ + if (line) + *line = m_endLine; + + if (col) + * col = m_endColumn; +} + +void AST::setParent(AST* parent) +{ +#ifndef CPPPARSER_NO_CHILDREN + if (m_parent) + m_parent->removeChild(this); +#endif + + m_parent = parent; + +#ifndef CPPPARSER_NO_CHILDREN + if (m_parent) + m_parent->appendChild(this); +#endif +} + +#ifndef CPPPARSER_NO_CHILDREN +void AST::appendChild(AST* child) +{ + m_children.append(child); +} + +void AST::removeChild(AST* child) +{ + m_children.removeOne(child); +} +#endif + +// ------------------------------------------------------------------------ +NameAST::NameAST() + : m_global(false) +{ +} + +void NameAST::setGlobal(bool b) +{ + m_global = b; +} + +void NameAST::setUnqualifiedName(ClassOrNamespaceNameAST::Node& unqualifiedName) +{ + m_unqualifiedName = unqualifiedName; + if (m_unqualifiedName.get()) m_unqualifiedName->setParent(this); +} + +void NameAST::addClassOrNamespaceName(ClassOrNamespaceNameAST::Node& classOrNamespaceName) +{ + if (!classOrNamespaceName.get()) + return; + + classOrNamespaceName->setParent(this); + m_classOrNamespaceNameList.append(classOrNamespaceName.release()); +} + +QString NameAST::text() const +{ + if (!m_unqualifiedName.get()) + return QString(); + + QString str; + + if (m_global) + str += "::"; + + for (int i = 0; i < m_classOrNamespaceNameList.size(); ++i) { + str += m_classOrNamespaceNameList.at(i)->text() + "::"; + } + + if (m_unqualifiedName.get()) + str += m_unqualifiedName->text(); + + return str; +} + +// ------------------------------------------------------------------------ +DeclarationAST::DeclarationAST() +{ +} + +// ------------------------------------------------------------------------ +LinkageBodyAST::LinkageBodyAST() +{ +} + +void LinkageBodyAST::addDeclaration(DeclarationAST::Node& ast) +{ + if (!ast.get()) + return; + + ast->setParent(this); + m_declarationList.append(ast.release()); +} + +// ------------------------------------------------------------------------ +LinkageSpecificationAST::LinkageSpecificationAST() +{ +} + +void LinkageSpecificationAST::setExternType(AST::Node& externType) +{ + m_externType = externType; + if (m_externType.get()) m_externType->setParent(this); +} + +void LinkageSpecificationAST::setLinkageBody(LinkageBodyAST::Node& linkageBody) +{ + m_linkageBody = linkageBody; + if (m_linkageBody.get()) m_linkageBody->setParent(this); +} + +void LinkageSpecificationAST::setDeclaration(DeclarationAST::Node& decl) +{ + m_declaration = decl; + if (m_declaration.get()) m_declaration->setParent(this); +} + +// ------------------------------------------------------------------------ +TranslationUnitAST::TranslationUnitAST() +{ +} + +void TranslationUnitAST::addDeclaration(DeclarationAST::Node& ast) +{ + if (!ast.get()) + return; + + ast->setParent(this); + m_declarationList.append(ast.release()); +} + +// ------------------------------------------------------------------------ +NamespaceAST::NamespaceAST() +{ +} + +void NamespaceAST::setNamespaceName(AST::Node& namespaceName) +{ + m_namespaceName = namespaceName; + if (m_namespaceName.get()) m_namespaceName->setParent(this); +} + +void NamespaceAST::setLinkageBody(LinkageBodyAST::Node& linkageBody) +{ + m_linkageBody = linkageBody; + if (m_linkageBody.get()) m_linkageBody->setParent(this); +} + + +// ------------------------------------------------------------------------ +NamespaceAliasAST::NamespaceAliasAST() +{ +} + +void NamespaceAliasAST::setNamespaceName(AST::Node& namespaceName) +{ + m_namespaceName = namespaceName; + if (m_namespaceName.get()) m_namespaceName->setParent(this); +} + +void NamespaceAliasAST::setAliasName(NameAST::Node& name) +{ + m_aliasName = name; + if (m_aliasName.get()) m_aliasName->setParent(this); +} + +// ------------------------------------------------------------------------ +UsingAST::UsingAST() +{ +} + +void UsingAST::setTypeName(AST::Node& typeName) +{ + m_typeName = typeName; + if (m_typeName.get()) m_typeName->setParent(this); +} + +void UsingAST::setName(NameAST::Node& name) +{ + m_name = name; + if (m_name.get()) m_name->setParent(this); +} + +// ------------------------------------------------------------------------ +UsingDirectiveAST::UsingDirectiveAST() +{ +} + +void UsingDirectiveAST::setName(NameAST::Node& name) +{ + m_name = name; + if (m_name.get()) m_name->setParent(this); +} + +TypedefAST::TypedefAST() +{ +} + +void TypeSpecifierAST::setName(NameAST::Node& name) +{ + m_name = name; + if (m_name.get()) m_name->setParent(this); +} + +void TypedefAST::setTypeSpec(TypeSpecifierAST::Node& typeSpec) +{ + m_typeSpec = typeSpec; + if (m_typeSpec.get()) m_typeSpec->setParent(this); +} + +void TypedefAST::setInitDeclaratorList(InitDeclaratorListAST::Node& initDeclaratorList) +{ + m_initDeclaratorList = initDeclaratorList; + if (m_initDeclaratorList.get()) m_initDeclaratorList->setParent(this); +} + +// ------------------------------------------------------------------------ +TemplateArgumentListAST::TemplateArgumentListAST() +{ +} + +void TemplateArgumentListAST::addArgument(AST::Node& arg) +{ + if (!arg.get()) + return; + + arg->setParent(this); + m_argumentList.append(arg.release()); +} + +QString TemplateArgumentListAST::text() const +{ + QStringList l; + + for (int i = 0; i < m_argumentList.size(); ++i) { + l.append(m_argumentList.at(i)->text()); + } + + return l.join(", "); +} + +// ------------------------------------------------------------------------ +TemplateDeclarationAST::TemplateDeclarationAST() +{ +} + +void TemplateDeclarationAST::setExported(AST::Node& exported) +{ + m_exported = exported; + if (m_exported.get()) m_exported->setParent(this); +} + +void TemplateDeclarationAST::setTemplateParameterList(TemplateParameterListAST::Node& templateParameterList) +{ + m_templateParameterList = templateParameterList; + if (m_templateParameterList.get()) m_templateParameterList->setParent(this); +} + +void TemplateDeclarationAST::setDeclaration(DeclarationAST::Node& declaration) +{ + m_declaration = declaration; + if (m_declaration.get()) m_declaration->setParent(this); +} + +// ------------------------------------------------------------------------ +ClassOrNamespaceNameAST::ClassOrNamespaceNameAST() +{ +} + +void ClassOrNamespaceNameAST::setName(AST::Node& name) +{ + m_name = name; + if (m_name.get()) m_name->setParent(this); +} + +void ClassOrNamespaceNameAST::setTemplateArgumentList(TemplateArgumentListAST::Node& templateArgumentList) +{ + m_templateArgumentList = templateArgumentList; + if (m_templateArgumentList.get()) m_templateArgumentList->setParent(this); +} + +QString ClassOrNamespaceNameAST::text() const +{ + if (!m_name.get()) + return QString(); + + QString str = m_name->text(); + if (m_templateArgumentList.get()) + str += QString::fromLatin1("< ") + m_templateArgumentList->text() + QString::fromLatin1(" >"); + + return str; +} + +// ------------------------------------------------------------------------ +TypeSpecifierAST::TypeSpecifierAST() +{ +} + +void TypeSpecifierAST::setCvQualify(GroupAST::Node& cvQualify) +{ + m_cvQualify = cvQualify; + if (m_cvQualify.get()) m_cvQualify->setParent(this); +} + +void TypeSpecifierAST::setCv2Qualify(GroupAST::Node& cv2Qualify) +{ + m_cv2Qualify = cv2Qualify; + if (m_cv2Qualify.get()) m_cv2Qualify->setParent(this); +} + +QString TypeSpecifierAST::text() const +{ + QString str; + + if (m_cvQualify.get()) + str += m_cvQualify->text() + ' '; + + if (m_name.get()) + str += m_name->text(); + + if (m_cv2Qualify.get()) + str += QString(" ") + m_cv2Qualify->text(); + + return str; +} + +// ------------------------------------------------------------------------ +ClassSpecifierAST::ClassSpecifierAST() +{ +} + +void ClassSpecifierAST::setClassKey(AST::Node& classKey) +{ + m_classKey = classKey; + if (m_classKey.get()) m_classKey->setParent(this); +} + +void ClassSpecifierAST::addDeclaration(DeclarationAST::Node& declaration) +{ + if (!declaration.get()) + return; + + declaration->setParent(this); + m_declarationList.append(declaration.release()); +} + +void ClassSpecifierAST::setBaseClause(BaseClauseAST::Node& baseClause) +{ + m_baseClause = baseClause; + if (m_baseClause.get()) m_baseClause->setParent(this); +} + +// ------------------------------------------------------------------------ +EnumSpecifierAST::EnumSpecifierAST() +{ +} + +void EnumSpecifierAST::addEnumerator(EnumeratorAST::Node& enumerator) +{ + if (!enumerator.get()) + return; + + enumerator->setParent(this); + m_enumeratorList.append(enumerator.release()); +} + + +// ------------------------------------------------------------------------ +ElaboratedTypeSpecifierAST::ElaboratedTypeSpecifierAST() +{ +} + +void ElaboratedTypeSpecifierAST::setKind(AST::Node& kind) +{ + m_kind = kind; + if (m_kind.get()) m_kind->setParent(this); +} + +QString ElaboratedTypeSpecifierAST::text() const +{ + if (m_kind.get()) + return m_kind->text() + ' ' + TypeSpecifierAST::text(); + + return TypeSpecifierAST::text(); +} + +// ------------------------------------------------------------------------ +StatementAST::StatementAST() +{ +} + +// ------------------------------------------------------------------------ +EnumeratorAST::EnumeratorAST() +{ +} + +void EnumeratorAST::setId(AST::Node& id) +{ + m_id = id; + if (m_id.get()) m_id->setParent(this); +} + +void EnumeratorAST::setExpr(AST::Node& expr) +{ + m_expr = expr; + if (m_expr.get()) m_expr->setParent(this); +} + +// ------------------------------------------------------------------------ +BaseClauseAST::BaseClauseAST() +{ +} + +void BaseClauseAST::addBaseSpecifier(BaseSpecifierAST::Node& baseSpecifier) +{ + if (!baseSpecifier.get()) + return; + + baseSpecifier->setParent(this); + m_baseSpecifierList.append(baseSpecifier.release()); +} + +// ------------------------------------------------------------------------ +BaseSpecifierAST::BaseSpecifierAST() +{ +} + +void BaseSpecifierAST::setIsVirtual(AST::Node& isVirtual) +{ + m_isVirtual = isVirtual; + if (m_isVirtual.get()) m_isVirtual->setParent(this); +} + +void BaseSpecifierAST::setAccess(AST::Node& access) +{ + m_access = access; + if (m_access.get()) m_access->setParent(this); +} + +void BaseSpecifierAST::setName(NameAST::Node& name) +{ + m_name = name; + if (m_name.get()) m_name->setParent(this); +} + +// ------------------------------------------------------------------------ +SimpleDeclarationAST::SimpleDeclarationAST() +{ +} + +void SimpleDeclarationAST::setFunctionSpecifier(GroupAST::Node& functionSpecifier) +{ + m_functionSpecifier = functionSpecifier; + if (m_functionSpecifier.get()) m_functionSpecifier->setParent(this); +} + +void SimpleDeclarationAST::setStorageSpecifier(GroupAST::Node& storageSpecifier) +{ + m_storageSpecifier = storageSpecifier; + if (m_storageSpecifier.get()) m_storageSpecifier->setParent(this); +} + +void SimpleDeclarationAST::setTypeSpec(TypeSpecifierAST::Node& typeSpec) +{ + m_typeSpec = typeSpec; + if (m_typeSpec.get()) m_typeSpec->setParent(this); +} + +void SimpleDeclarationAST::setInitDeclaratorList(InitDeclaratorListAST::Node& initDeclaratorList) +{ + m_initDeclaratorList = initDeclaratorList; + if (m_initDeclaratorList.get()) m_initDeclaratorList->setParent(this); +} + +void SimpleDeclarationAST::setWinDeclSpec(GroupAST::Node& winDeclSpec) +{ + m_winDeclSpec = winDeclSpec; + if (m_winDeclSpec.get()) m_winDeclSpec->setParent(this); +} + + +// ------------------------------------------------------------------------ +InitDeclaratorListAST::InitDeclaratorListAST() +{ +} + +void InitDeclaratorListAST::addInitDeclarator(InitDeclaratorAST::Node& decl) +{ + if (!decl.get()) + return; + + decl->setParent(this); + m_initDeclaratorList.append(decl.release()); +} + +// ------------------------------------------------------------------------ +DeclaratorAST::DeclaratorAST() +{ +} + +void DeclaratorAST::setSubDeclarator(DeclaratorAST::Node& subDeclarator) +{ + m_subDeclarator = subDeclarator; + if (m_subDeclarator.get()) m_subDeclarator->setParent(this); +} + +void DeclaratorAST::setDeclaratorId(NameAST::Node& declaratorId) +{ + m_declaratorId = declaratorId; + if (m_declaratorId.get()) m_declaratorId->setParent(this); +} + +void DeclaratorAST::setBitfieldInitialization(AST::Node& bitfieldInitialization) +{ + m_bitfieldInitialization = bitfieldInitialization; + if (m_bitfieldInitialization.get()) m_bitfieldInitialization->setParent(this); +} + +void DeclaratorAST::addArrayDimension(AST::Node& arrayDimension) +{ + if (!arrayDimension.get()) + return; + + arrayDimension->setParent(this); + m_arrayDimensionList.append(arrayDimension.release()); +} + +void DeclaratorAST::setParameterDeclarationClause(AUTO_PTR& parameterDeclarationClause) +{ + m_parameterDeclarationClause = parameterDeclarationClause; + if (m_parameterDeclarationClause.get()) m_parameterDeclarationClause->setParent(this); +} + +void DeclaratorAST::setConstant(AST::Node& constant) +{ + m_constant = constant; + if (m_constant.get()) m_constant->setParent(this); +} + +void DeclaratorAST::setExceptionSpecification(GroupAST::Node& exceptionSpecification) +{ + m_exceptionSpecification = exceptionSpecification; + if (m_exceptionSpecification.get()) m_exceptionSpecification->setParent(this); +} + +void DeclaratorAST::addPtrOp(AST::Node& ptrOp) +{ + if (!ptrOp.get()) + return; + + ptrOp->setParent(this); + m_ptrOpList.append(ptrOp.release()); +} + +// -------------------------------------------------------------------------- +InitDeclaratorAST::InitDeclaratorAST() +{ +} + +void InitDeclaratorAST::setDeclarator(DeclaratorAST::Node& declarator) +{ + m_declarator = declarator; + if (m_declarator.get()) m_declarator->setParent(this); +} + +void InitDeclaratorAST::setInitializer(AST::Node& initializer) +{ + m_initializer = initializer; + if (m_initializer.get()) m_initializer->setParent(this); +} + +// -------------------------------------------------------------------------- +FunctionDefinitionAST::FunctionDefinitionAST() +{ +} + +void FunctionDefinitionAST::setFunctionSpecifier(GroupAST::Node& functionSpecifier) +{ + m_functionSpecifier = functionSpecifier; + if (m_functionSpecifier.get()) m_functionSpecifier->setParent(this); +} + +void FunctionDefinitionAST::setStorageSpecifier(GroupAST::Node& storageSpecifier) +{ + m_storageSpecifier = storageSpecifier; + if (m_storageSpecifier.get()) m_storageSpecifier->setParent(this); +} + +void FunctionDefinitionAST::setTypeSpec(TypeSpecifierAST::Node& typeSpec) +{ + m_typeSpec = typeSpec; + if (m_typeSpec.get()) m_typeSpec->setParent(this); +} + +void FunctionDefinitionAST::setInitDeclarator(InitDeclaratorAST::Node& initDeclarator) +{ + m_initDeclarator = initDeclarator; + if (m_initDeclarator.get()) m_initDeclarator->setParent(this); +} + +void FunctionDefinitionAST::setFunctionBody(StatementListAST::Node& functionBody) +{ + m_functionBody = functionBody; + if (m_functionBody.get()) m_functionBody->setParent(this); +} + +void FunctionDefinitionAST::setWinDeclSpec(GroupAST::Node& winDeclSpec) +{ + m_winDeclSpec = winDeclSpec; + if (m_winDeclSpec.get()) m_winDeclSpec->setParent(this); +} + +// -------------------------------------------------------------------------- +StatementListAST::StatementListAST() +{ +} + +void StatementListAST::addStatement(StatementAST::Node& statement) +{ + if (!statement.get()) + return; + + statement->setParent(this); + m_statementList.append(statement.release()); +} + +// -------------------------------------------------------------------------- +IfStatementAST::IfStatementAST() +{ +} + +void IfStatementAST::setCondition(ConditionAST::Node& condition) +{ + m_condition = condition; + if (m_condition.get()) m_condition->setParent(this); +} + +void IfStatementAST::setStatement(StatementAST::Node& statement) +{ + m_statement = statement; + if (m_statement.get()) m_statement->setParent(this); +} + +void IfStatementAST::setElseStatement(StatementAST::Node& elseStatement) +{ + m_elseStatement = elseStatement; + if (m_elseStatement.get()) m_elseStatement->setParent(this); +} + +// -------------------------------------------------------------------------- +WhileStatementAST::WhileStatementAST() +{ +} + +void WhileStatementAST::setCondition(ConditionAST::Node& condition) +{ + m_condition = condition; + if (m_condition.get()) m_condition->setParent(this); +} + +void WhileStatementAST::setStatement(StatementAST::Node& statement) +{ + m_statement = statement; + if (m_statement.get()) m_statement->setParent(this); +} + +// -------------------------------------------------------------------------- +DoStatementAST::DoStatementAST() +{ +} + +void DoStatementAST::setCondition(ConditionAST::Node& condition) +{ + m_condition = condition; + if (m_condition.get()) m_condition->setParent(this); +} + +void DoStatementAST::setStatement(StatementAST::Node& statement) +{ + m_statement = statement; + if (m_statement.get()) m_statement->setParent(this); +} + +// -------------------------------------------------------------------------- +ForStatementAST::ForStatementAST() +{ +} + +void ForStatementAST::setCondition(ConditionAST::Node& condition) +{ + m_condition = condition; + if (m_condition.get()) m_condition->setParent(this); +} + +void ForStatementAST::setExpression(AST::Node& expression) +{ + m_expression = expression; + if (m_expression.get()) m_expression->setParent(this); +} + +void ForStatementAST::setStatement(StatementAST::Node& statement) +{ + m_statement = statement; + if (m_statement.get()) m_statement->setParent(this); +} + +void ForStatementAST::setInitStatement(StatementAST::Node& initStatement) +{ + m_initStatement = initStatement; + if (m_initStatement.get()) m_initStatement->setParent(this); +} + +// -------------------------------------------------------------------------- +ForEachStatementAST::ForEachStatementAST() +{ +} + +void ForEachStatementAST::setExpression(AST::Node& expression) +{ + m_expression = expression; + if (m_expression.get()) m_expression->setParent(this); +} + +void ForEachStatementAST::setStatement(StatementAST::Node& statement) +{ + m_statement = statement; + if (m_statement.get()) m_statement->setParent(this); +} + +void ForEachStatementAST::setInitStatement(StatementAST::Node& initStatement) +{ + m_initStatement = initStatement; + if (m_initStatement.get()) m_initStatement->setParent(this); +} + +// -------------------------------------------------------------------------- +SwitchStatementAST::SwitchStatementAST() +{ +} + +void SwitchStatementAST::setCondition(ConditionAST::Node& condition) +{ + m_condition = condition; + if (m_condition.get()) m_condition->setParent(this); +} + +void SwitchStatementAST::setStatement(StatementAST::Node& statement) +{ + m_statement = statement; + if (m_statement.get()) m_statement->setParent(this); +} + +// -------------------------------------------------------------------------- +CatchStatementListAST::CatchStatementListAST() +{ +} + +void CatchStatementListAST::addStatement(CatchStatementAST::Node& statement) +{ + if (!statement.get()) + return; + + statement->setParent(this); + m_statementList.append(statement.release()); +} + +// -------------------------------------------------------------------------- +CatchStatementAST::CatchStatementAST() +{ +} + +void CatchStatementAST::setCondition(ConditionAST::Node& condition) +{ + m_condition = condition; + if (m_condition.get()) m_condition->setParent(this); +} + +void CatchStatementAST::setStatement(StatementAST::Node& statement) +{ + m_statement = statement; + if (m_statement.get()) m_statement->setParent(this); +} + +// -------------------------------------------------------------------------- +TryBlockStatementAST::TryBlockStatementAST() +{ +} + +void TryBlockStatementAST::setStatement(StatementAST::Node& statement) +{ + m_statement = statement; + if (m_statement.get()) m_statement->setParent(this); +} + +void TryBlockStatementAST::setCatchStatementList(CatchStatementListAST::Node& statementList) +{ + m_catchStatementList = statementList; + if (m_catchStatementList.get()) m_catchStatementList->setParent(this); +} + +// -------------------------------------------------------------------------- +DeclarationStatementAST::DeclarationStatementAST() +{ +} + +void DeclarationStatementAST::setDeclaration(DeclarationAST::Node& declaration) +{ + m_declaration = declaration; + if (m_declaration.get()) m_declaration->setParent(this); +} + +// -------------------------------------------------------------------------- +ExpressionStatementAST::ExpressionStatementAST() +{ +} + +void ExpressionStatementAST::setExpression(AST::Node& expression) +{ + m_expression = expression; + if (m_expression.get()) m_expression->setParent(this); +} + + +// -------------------------------------------------------------------------- +ParameterDeclarationAST::ParameterDeclarationAST() +{ +} + +void ParameterDeclarationAST::setTypeSpec(TypeSpecifierAST::Node& typeSpec) +{ + m_typeSpec = typeSpec; + if (m_typeSpec.get()) m_typeSpec->setParent(this); +} + +void ParameterDeclarationAST::setDeclarator(DeclaratorAST::Node& declarator) +{ + m_declarator = declarator; + if (m_declarator.get()) m_declarator->setParent(this); +} + +void ParameterDeclarationAST::setExpression(AST::Node& expression) +{ + m_expression = expression; + if (m_expression.get()) m_expression->setParent(this); +} + +QString ParameterDeclarationAST::text() const +{ + QString str; + if (m_typeSpec.get()) + str += m_typeSpec->text() + ' '; + + if (m_declarator.get()) + str += m_declarator->text(); + + if (m_expression.get()) + str += QString(" = ") + m_expression->text(); + + return str; +} + +// -------------------------------------------------------------------------- +ParameterDeclarationListAST::ParameterDeclarationListAST() +{ +} + +void ParameterDeclarationListAST::addParameter(ParameterDeclarationAST::Node& parameter) +{ + if (!parameter.get()) + return; + + parameter->setParent(this); + m_parameterList.append(parameter.release()); +} + +QString ParameterDeclarationListAST::text() const +{ + QStringList l; + for (int i = 0; i < m_parameterList.size(); ++i) { + l.append(m_parameterList.at(i)->text()); + } + return l.join(", "); +} + + +// -------------------------------------------------------------------------- +ParameterDeclarationClauseAST::ParameterDeclarationClauseAST() +{ +} + +void ParameterDeclarationClauseAST::setParameterDeclarationList(ParameterDeclarationListAST::Node& parameterDeclarationList) +{ + m_parameterDeclarationList = parameterDeclarationList; + if (m_parameterDeclarationList.get()) m_parameterDeclarationList->setParent(this); +} + +void ParameterDeclarationClauseAST::setEllipsis(AST::Node& ellipsis) +{ + m_ellipsis = ellipsis; + if (m_ellipsis.get()) m_ellipsis->setParent(this); +} + +QString ParameterDeclarationClauseAST::text() const +{ + QString str; + + if (m_parameterDeclarationList.get()) + str += m_parameterDeclarationList->text(); + + if (m_ellipsis.get()) + str += " ..."; + + return str; +} + + +// -------------------------------------------------------------------------- +GroupAST::GroupAST() +{ +} + +void GroupAST::addNode(AST::Node& node) +{ + if (!node.get()) + return; + + node->setParent(this); + m_nodeList.append(node.release()); +} + +QString GroupAST::text() const +{ + QStringList l; + for (int i = 0; i < m_nodeList.size(); ++i) { + l.append(m_nodeList.at(i)->text()); + } + return l.join(" "); +} + +// -------------------------------------------------------------------------- +AccessDeclarationAST::AccessDeclarationAST() +{ +} + +void AccessDeclarationAST::addAccess(AST::Node& access) +{ + if (!access.get()) + return; + + access->setParent(this); + m_accessList.append(access.release()); +} + +QString AccessDeclarationAST::text() const +{ + QStringList l; + for (int i = 0; i < m_accessList.size(); ++i) { + l.append(m_accessList.at(i)->text()); + } + return l.join(" "); +} + +// -------------------------------------------------------------------------- +TypeParameterAST::TypeParameterAST() +{ +} + +void TypeParameterAST::setKind(AST::Node& kind) +{ + m_kind = kind; + if (m_kind.get()) m_kind->setParent(this); +} + +void TypeParameterAST::setTemplateParameterList(AUTO_PTR& templateParameterList) +{ + m_templateParameterList = templateParameterList; + if (m_templateParameterList.get()) m_templateParameterList->setParent(this); +} + +void TypeParameterAST::setName(NameAST::Node& name) +{ + m_name = name; + if (m_name.get()) m_name->setParent(this); +} + +void TypeParameterAST::setTypeId(AST::Node& typeId) +{ + m_typeId = typeId; + if (m_typeId.get()) m_typeId->setParent(this); +} + +// -------------------------------------------------------------------------- +TemplateParameterAST::TemplateParameterAST() +{ +} + +void TemplateParameterAST::setTypeParameter(TypeParameterAST::Node& typeParameter) +{ + m_typeParameter = typeParameter; + if (m_typeParameter.get()) m_typeParameter->setParent(this); +} + +void TemplateParameterAST::setTypeValueParameter(ParameterDeclarationAST::Node& typeValueParameter) +{ + m_typeValueParameter = typeValueParameter; + if (m_typeValueParameter.get()) m_typeValueParameter->setParent(this); +} + +// -------------------------------------------------------------------------- +TemplateParameterListAST::TemplateParameterListAST() +{ +} + +void TemplateParameterListAST::addTemplateParameter(TemplateParameterAST::Node& templateParameter) +{ + if (!templateParameter.get()) + return; + + templateParameter->setParent(this); + m_templateParameterList.append(templateParameter.release()); +} + +// -------------------------------------------------------------------------- +ConditionAST::ConditionAST() +{ +} + +void ConditionAST::setTypeSpec(TypeSpecifierAST::Node& typeSpec) +{ + m_typeSpec = typeSpec; + if (m_typeSpec.get()) m_typeSpec->setParent(this); +} + +void ConditionAST::setDeclarator(DeclaratorAST::Node& declarator) +{ + m_declarator = declarator; + if (m_declarator.get()) m_declarator->setParent(this); +} + +void ConditionAST::setExpression(AST::Node& expression) +{ + m_expression = expression; + if (m_expression.get()) m_expression->setParent(this); +} + +void ClassSpecifierAST::setWinDeclSpec(GroupAST::Node & winDeclSpec) +{ + m_winDeclSpec = winDeclSpec; + if (m_winDeclSpec.get()) m_winDeclSpec->setParent(this); +} diff -Nru umbrello-4.12.3/lib/cppparser/ast.h umbrello-4.12.90/lib/cppparser/ast.h --- umbrello-4.12.3/lib/cppparser/ast.h 1970-01-01 00:00:00.000000000 +0000 +++ umbrello-4.12.90/lib/cppparser/ast.h 2014-03-05 15:04:09.000000000 +0000 @@ -0,0 +1,1921 @@ +/* This file is part of KDevelop + Copyright (C) 2002, 2003 Roberto Raggi + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef __ast_h +#define __ast_h + +#include + +#include +#include +#include + +#if defined(Q_OS_WIN32) || defined(Q_CC_SUN) + +#ifndef _THROW0 +# define _THROW0() +#endif + +template class AUTO_PTR +{ +private: + _Tp* _M_ptr; + +public: + typedef _Tp element_type; + + explicit AUTO_PTR(_Tp* __p = 0) _THROW0() : _M_ptr(__p) {} + + template AUTO_PTR(AUTO_PTR<_Tp1>& __a) _THROW0() + : _M_ptr(__a.release()) {} + + AUTO_PTR(AUTO_PTR& __a) _THROW0() : _M_ptr(__a.release()) {} + + + + template + AUTO_PTR& operator=(AUTO_PTR<_Tp1>& __a) _THROW0() + { + if (__a.get() != this->get()) { + delete _M_ptr; + _M_ptr = __a.release(); + } + return *this; + } + + AUTO_PTR& operator=(AUTO_PTR& __a) _THROW0() + { + if (&__a != this) { + delete _M_ptr; + _M_ptr = __a.release(); + } + return *this; + } + + ~AUTO_PTR() _THROW0() + { + delete _M_ptr; + } + + _Tp& operator*() const _THROW0() + { + return *_M_ptr; + } + _Tp* operator->() const _THROW0() + { + return _M_ptr; + } + _Tp* get() const _THROW0() + { + return _M_ptr; + } + _Tp* release() _THROW0() + { + _Tp* __tmp = _M_ptr; + _M_ptr = 0; + return __tmp; + } + void reset(_Tp* __p = 0) _THROW0() + { + delete _M_ptr; + _M_ptr = __p; + } + + // According to the C++ standard, these conversions are required. Most + // present-day compilers, however, do not enforce that requirement---and, + // in fact, most present-day compilers do not support the language + // features that these conversions rely on. + + +private: + template struct AUTO_PTR_ref { + _Tp1* _M_ptr; + AUTO_PTR_ref(_Tp1* __p) : _M_ptr(__p) {} + }; + +public: + AUTO_PTR(AUTO_PTR_ref<_Tp> __ref) _THROW0() + : _M_ptr(__ref._M_ptr) {} + template operator AUTO_PTR_ref<_Tp1>() _THROW0() + { + return AUTO_PTR_ref<_Tp>(this->release()); + } + template operator AUTO_PTR<_Tp1>() _THROW0() + { + return AUTO_PTR<_Tp1>(this->release()); + } + +}; + +#else +#define AUTO_PTR std::auto_ptr +#endif + +template typename T::Node CreateNode() +{ + typename T::Node node(new T); + node->setNodeType(T::Type); + return node; +} + +template typename T::Node NullNode() +{ + typename T::Node node; + return node; +} + +enum NodeType { + NodeType_Generic = 0, + + NodeType_TemplateArgumentList = 1000, + NodeType_ClassOrNamespaceName, + NodeType_Name, + NodeType_Declaration, + NodeType_TypeSpecifier, + NodeType_BaseSpecifier, + NodeType_BaseClause, + NodeType_ClassSpecifier, + NodeType_Enumerator, + NodeType_EnumSpecifier, + NodeType_ElaboratedTypeSpecifier, + NodeType_LinkageBody, + NodeType_LinkageSpecification, + NodeType_Namespace, + NodeType_NamespaceAlias, + NodeType_Using, + NodeType_UsingDirective, + NodeType_InitDeclaratorList, + NodeType_Typedef, + NodeType_Declarator, + NodeType_InitDeclarator, + NodeType_TemplateDeclaration, + NodeType_SimpleDeclaration, + NodeType_Statement, + NodeType_StatementList, + NodeType_IfStatement, + NodeType_WhileStatement, + NodeType_DoStatement, + NodeType_ForStatement, + NodeType_ForEachStatement, // qt4 [erbsland] + NodeType_SwitchStatement, + NodeType_CatchStatement, + NodeType_CatchStatementList, + NodeType_TryBlockStatement, + NodeType_DeclarationStatement, + NodeType_TranslationUnit, + NodeType_FunctionDefinition, + NodeType_ExpressionStatement, + NodeType_ParameterDeclaration, + NodeType_ParameterDeclarationList, + NodeType_ParameterDeclarationClause, + NodeType_Group, + NodeType_AccessDeclaration, + NodeType_TypeParameter, + NodeType_TemplateParameter, + NodeType_TemplateParameterList, + NodeType_Condition, + NodeType_File, + + NodeType_Custom = 2000 +}; + +QString nodeTypeToString(int type); + + +#if defined(CPPPARSER_QUICK_ALLOCATOR) + +#include + +#define DECLARE_ALLOC(tp) \ + void * operator new(std::size_t) \ + { \ + return quick_allocator< tp >::alloc(); \ + } \ + \ + void operator delete(void * p) \ + { \ + quick_allocator< tp >::dealloc(p); \ + } +#else + +#define DECLARE_ALLOC(tp) + +#endif + +struct Slice { + QString source; + int position; + int length; + + inline Slice() + : position(0), length(0) {} +}; + + +class CommentAST +{ + QString m_comment; +public: + void setComment(const QString& comment) + { + m_comment = comment; + } + + void addComment(const QString& comment) + { + if (!m_comment.isEmpty()) { + m_comment += "\n(" + comment + ")"; + } else { + m_comment = comment; + } + } + + QString comment() const + { + return m_comment; + } + + bool haveComment() const + { + return !m_comment.isEmpty(); + } +}; + +class AST : public CommentAST +{ +public: + typedef AUTO_PTR Node; + enum { Type=NodeType_Generic }; + + DECLARE_ALLOC(AST) + +public: + AST(); + virtual ~AST(); + + int nodeType() const + { + return m_nodeType; + } + void setNodeType(int nodeType) + { + m_nodeType = nodeType; + } + + AST* parent() + { + return m_parent; + } + void setParent(AST* parent); + + void setStartPosition(int line, int col); + void getStartPosition(int* line, int* col) const; + + void setEndPosition(int line, int col); + void getEndPosition(int* line, int* col) const; + +#ifndef CPPPARSER_NO_CHILDREN + QList children() + { + return m_children; + } + void appendChild(AST* child); + void removeChild(AST* child); +#endif + + virtual inline QString text() const + { + return m_slice.source.mid(m_slice.position, m_slice.length); + } + + inline void setSlice(const Slice& slice) + { + m_slice = slice; + } + + inline void setSlice(const QString &text, int position, int length) + { + CommentAST a; + m_slice.source = text; + m_slice.position = position; + m_slice.length = length; + } + + inline void setText(const QString &text) + { + setSlice(text, 0, text.length()); + } + +private: + int m_nodeType; + AST* m_parent; + int m_startLine, m_startColumn; + int m_endLine, m_endColumn; + Slice m_slice; +#ifndef CPPPARSER_NO_CHILDREN + QList m_children; +#endif + +private: + AST(const AST& source); + void operator = (const AST& source); +}; + +class GroupAST: public AST +{ +public: + typedef AUTO_PTR Node; + enum { Type = NodeType_Group }; + + DECLARE_ALLOC(GroupAST) + +public: + GroupAST(); + + QList nodeList() + { + return m_nodeList; + } + void addNode(AST::Node& node); + + virtual QString text() const; + +private: + QList m_nodeList; + +private: + GroupAST(const GroupAST& source); + void operator = (const GroupAST& source); +}; + + +class TemplateArgumentListAST: public AST +{ +public: + typedef AUTO_PTR Node; + enum { Type = NodeType_TemplateArgumentList }; + + DECLARE_ALLOC(TemplateArgumentListAST) + +public: + TemplateArgumentListAST(); + + void addArgument(AST::Node& arg); + QList argumentList() + { + return m_argumentList; + } + + virtual QString text() const; + +private: + QList m_argumentList; + +private: + TemplateArgumentListAST(const TemplateArgumentListAST& source); + void operator = (const TemplateArgumentListAST& source); +}; + +class ClassOrNamespaceNameAST: public AST +{ +public: + typedef AUTO_PTR Node; + enum { Type = NodeType_ClassOrNamespaceName }; + + DECLARE_ALLOC(ClassOrNamespaceNameAST) + +public: + ClassOrNamespaceNameAST(); + + AST* name() + { + return m_name.get(); + } + void setName(AST::Node& name); + + TemplateArgumentListAST* templateArgumentList() + { + return m_templateArgumentList.get(); + } + void setTemplateArgumentList(TemplateArgumentListAST::Node& templateArgumentList); + + virtual QString text() const; + +private: + AST::Node m_name; + TemplateArgumentListAST::Node m_templateArgumentList; + +private: + ClassOrNamespaceNameAST(const ClassOrNamespaceNameAST& source); + void operator = (const ClassOrNamespaceNameAST& source); +}; + +class NameAST: public AST +{ +public: + typedef AUTO_PTR Node; + enum { Type = NodeType_Name }; + + DECLARE_ALLOC(NameAST) + +public: + NameAST(); + + bool isGlobal() const + { + return m_global; + } + void setGlobal(bool b); + + void addClassOrNamespaceName(ClassOrNamespaceNameAST::Node& classOrNamespaceName); + QList classOrNamespaceNameList() + { + return m_classOrNamespaceNameList; + } + + ClassOrNamespaceNameAST* unqualifiedName() + { + return m_unqualifiedName.get(); + } + void setUnqualifiedName(ClassOrNamespaceNameAST::Node& unqualifiedName); + + virtual QString text() const; + +private: + bool m_global; + ClassOrNamespaceNameAST::Node m_unqualifiedName; + QList m_classOrNamespaceNameList; + +private: + NameAST(const NameAST& source); + void operator = (const NameAST& source); +}; + +class TypeParameterAST: public AST +{ +public: + typedef AUTO_PTR Node; + enum { Type = NodeType_TypeParameter }; + + DECLARE_ALLOC(TypeParameterAST) + +public: + TypeParameterAST(); + + AST* kind() + { + return m_kind.get(); + } + void setKind(AST::Node& kind); + + class TemplateParameterListAST* templateParameterList() + { + return m_templateParameterList.get(); + } + void setTemplateParameterList(AUTO_PTR& templateParameterList); + + NameAST* name() + { + return m_name.get(); + } + void setName(NameAST::Node& name); + + AST* typeId() + { + return m_typeId.get(); + } + void setTypeId(AST::Node& typeId); + +private: + AST::Node m_kind; + AUTO_PTR m_templateParameterList; + NameAST::Node m_name; + AST::Node m_typeId; + +private: + TypeParameterAST(const TypeParameterAST& source); + void operator = (const TypeParameterAST& source); +}; + +class DeclarationAST: public AST +{ +public: + typedef AUTO_PTR Node; + enum { Type = NodeType_Declaration }; + + DECLARE_ALLOC(DeclarationAST) + +public: + DeclarationAST(); + +private: + DeclarationAST(const DeclarationAST& source); + void operator = (const DeclarationAST& source); +}; + +class AccessDeclarationAST: public DeclarationAST +{ +public: + typedef AUTO_PTR Node; + enum { Type = NodeType_AccessDeclaration }; + + DECLARE_ALLOC(AccessDeclarationAST) + +public: + AccessDeclarationAST(); + + QList accessList() + { + return m_accessList; + } + void addAccess(AST::Node& access); + + virtual QString text() const; + +private: + QList m_accessList; + +private: + AccessDeclarationAST(const AccessDeclarationAST& source); + void operator = (const AccessDeclarationAST& source); +}; + +class TypeSpecifierAST: public AST +{ +public: + typedef AUTO_PTR Node; + enum { Type = NodeType_TypeSpecifier }; + + DECLARE_ALLOC(TypeSpecifierAST) + +public: + TypeSpecifierAST(); + + virtual NameAST* name() + { + return m_name.get(); + } + virtual void setName(NameAST::Node& name); + + GroupAST* cvQualify() + { + return m_cvQualify.get(); + } + void setCvQualify(GroupAST::Node& cvQualify); + + GroupAST* cv2Qualify() + { + return m_cv2Qualify.get(); + } + void setCv2Qualify(GroupAST::Node& cv2Qualify); + + virtual QString text() const; + +private: + NameAST::Node m_name; + GroupAST::Node m_cvQualify; + GroupAST::Node m_cv2Qualify; + +private: + TypeSpecifierAST(const TypeSpecifierAST& source); + void operator = (const TypeSpecifierAST& source); +}; + +class BaseSpecifierAST: public AST +{ +public: + typedef AUTO_PTR Node; + enum { Type = NodeType_BaseSpecifier }; + + DECLARE_ALLOC(BaseSpecifierAST) + +public: + BaseSpecifierAST(); + + AST* isVirtual() + { + return m_isVirtual.get(); + } + void setIsVirtual(AST::Node& isVirtual); + + AST* access() + { + return m_access.get(); + } + void setAccess(AST::Node& access); + + NameAST* name() + { + return m_name.get(); + } + void setName(NameAST::Node& name); + +private: + AST::Node m_isVirtual; + AST::Node m_access; + NameAST::Node m_name; + +private: + BaseSpecifierAST(const BaseSpecifierAST& source); + void operator = (const BaseSpecifierAST& source); +}; + +class BaseClauseAST: public AST +{ +public: + typedef AUTO_PTR Node; + enum { Type = NodeType_BaseClause }; + + DECLARE_ALLOC(BaseClauseAST) + +public: + BaseClauseAST(); + + void addBaseSpecifier(BaseSpecifierAST::Node& baseSpecifier); + QList baseSpecifierList() + { + return m_baseSpecifierList; + } + +private: + QList m_baseSpecifierList; + +private: + BaseClauseAST(const BaseClauseAST& source); + void operator = (const BaseClauseAST& source); +}; + +class ClassSpecifierAST: public TypeSpecifierAST +{ +public: + typedef AUTO_PTR Node; + enum { Type = NodeType_ClassSpecifier }; + + DECLARE_ALLOC(ClassSpecifierAST) + +public: + ClassSpecifierAST(); + + GroupAST* winDeclSpec() + { + return m_winDeclSpec.get(); + } + void setWinDeclSpec(GroupAST::Node& winDeclSpec); + + AST* classKey() + { + return m_classKey.get(); + } + void setClassKey(AST::Node& classKey); + + BaseClauseAST* baseClause() + { + return m_baseClause.get(); + } + void setBaseClause(BaseClauseAST::Node& baseClause); + + QList declarationList() + { + return m_declarationList; + } + void addDeclaration(DeclarationAST::Node& declaration); + +private: + GroupAST::Node m_winDeclSpec; + AST::Node m_classKey; + BaseClauseAST::Node m_baseClause; + QList m_declarationList; + +private: + ClassSpecifierAST(const ClassSpecifierAST& source); + void operator = (const ClassSpecifierAST& source); +}; + +class EnumeratorAST: public AST +{ +public: + typedef AUTO_PTR Node; + enum { Type = NodeType_Enumerator }; + + DECLARE_ALLOC(EnumeratorAST) + +public: + EnumeratorAST(); + + AST* id() + { + return m_id.get(); + } + void setId(AST::Node& id); + + AST* expr() + { + return m_expr.get(); + } + void setExpr(AST::Node& expr); + +private: + AST::Node m_id; + AST::Node m_expr; + +private: + EnumeratorAST(const EnumeratorAST& source); + void operator = (const EnumeratorAST& source); +}; + +class EnumSpecifierAST: public TypeSpecifierAST +{ +public: + typedef AUTO_PTR Node; + enum { Type = NodeType_EnumSpecifier }; + + DECLARE_ALLOC(EnumSpecifierAST) + +public: + EnumSpecifierAST(); + + void addEnumerator(EnumeratorAST::Node& enumerator); + QList enumeratorList() + { + return m_enumeratorList; + } + +private: + QList m_enumeratorList; + +private: + EnumSpecifierAST(const EnumSpecifierAST& source); + void operator = (const EnumSpecifierAST& source); +}; + +class ElaboratedTypeSpecifierAST: public TypeSpecifierAST +{ +public: + typedef AUTO_PTR Node; + enum { Type = NodeType_ElaboratedTypeSpecifier }; + + DECLARE_ALLOC(ElaboratedTypeSpecifierAST) + +public: + ElaboratedTypeSpecifierAST(); + + AST* kind() + { + return m_kind.get(); + } + void setKind(AST::Node& kind); + + virtual QString text() const; + +private: + AST::Node m_kind; + +private: + ElaboratedTypeSpecifierAST(const ElaboratedTypeSpecifierAST& source); + void operator = (const ElaboratedTypeSpecifierAST& source); +}; + +class LinkageBodyAST: public AST +{ +public: + typedef AUTO_PTR Node; + enum { Type = NodeType_LinkageBody }; + + DECLARE_ALLOC(LinkageBodyAST) + +public: + LinkageBodyAST(); + + void addDeclaration(DeclarationAST::Node& ast); + QList declarationList() + { + return m_declarationList; + } + +private: + QList m_declarationList; + +private: + LinkageBodyAST(const LinkageBodyAST& source); + void operator = (const LinkageBodyAST& source); +}; + +class LinkageSpecificationAST: public DeclarationAST +{ +public: + typedef AUTO_PTR Node; + enum { Type = NodeType_LinkageSpecification }; + + DECLARE_ALLOC(LinkageSpecificationAST) + +public: + LinkageSpecificationAST(); + + AST* externType() + { + return m_externType.get(); + } + void setExternType(AST::Node& externType); + + LinkageBodyAST* linkageBody() + { + return m_linkageBody.get(); + } + void setLinkageBody(LinkageBodyAST::Node& linkageBody); + + DeclarationAST* declaration() + { + return m_declaration.get(); + } + void setDeclaration(DeclarationAST::Node& decl); + +private: + AST::Node m_externType; + LinkageBodyAST::Node m_linkageBody; + DeclarationAST::Node m_declaration; + +private: + LinkageSpecificationAST(const LinkageSpecificationAST& source); + void operator = (const LinkageSpecificationAST& source); +}; + +class NamespaceAST: public DeclarationAST +{ +public: + typedef AUTO_PTR Node; + enum { Type = NodeType_Namespace }; + + DECLARE_ALLOC(NamespaceAST) + +public: + NamespaceAST(); + + AST* namespaceName() + { + return m_namespaceName.get(); + } + void setNamespaceName(AST::Node& namespaceName); + + LinkageBodyAST* linkageBody() + { + return m_linkageBody.get(); + } + void setLinkageBody(LinkageBodyAST::Node& linkageBody); + +private: + AST::Node m_namespaceName; + LinkageBodyAST::Node m_linkageBody; + +private: + NamespaceAST(const NamespaceAST& source); + void operator = (const NamespaceAST& source); +}; + +class NamespaceAliasAST: public DeclarationAST +{ +public: + typedef AUTO_PTR Node; + enum { Type = NodeType_NamespaceAlias }; + + DECLARE_ALLOC(NamespaceAliasAST) + +public: + NamespaceAliasAST(); + + AST* namespaceName() + { + return m_namespaceName.get(); + } + void setNamespaceName(AST::Node& name); + + NameAST* aliasName() + { + return m_aliasName.get(); + } + void setAliasName(NameAST::Node& name); + +private: + AST::Node m_namespaceName; + NameAST::Node m_aliasName; + +private: + NamespaceAliasAST(const NamespaceAliasAST& source); + void operator = (const NamespaceAliasAST& source); +}; + +class UsingAST: public DeclarationAST +{ +public: + typedef AUTO_PTR Node; + enum { Type = NodeType_Using }; + + DECLARE_ALLOC(UsingAST) + +public: + UsingAST(); + + AST* typeName() + { + return m_typeName.get(); + } + void setTypeName(AST::Node& typeName); + + NameAST* name() + { + return m_name.get(); + } + void setName(NameAST::Node& name); + +private: + AST::Node m_typeName; + NameAST::Node m_name; + +private: + UsingAST(const UsingAST& source); + void operator = (const UsingAST& source); +}; + +class UsingDirectiveAST: public DeclarationAST +{ +public: + typedef AUTO_PTR Node; + enum { Type = NodeType_UsingDirective }; + + DECLARE_ALLOC(UsingDirectiveAST) + +public: + UsingDirectiveAST(); + + NameAST* name() + { + return m_name.get(); + } + void setName(NameAST::Node& name); + +private: + NameAST::Node m_name; + +private: + UsingDirectiveAST(const UsingDirectiveAST& source); + void operator = (const UsingDirectiveAST& source); +}; + +class DeclaratorAST: public AST +{ +public: + typedef AUTO_PTR Node; + enum { Type = NodeType_Declarator }; + + DECLARE_ALLOC(DeclaratorAST) + +public: + DeclaratorAST(); + + QList ptrOpList() + { + return m_ptrOpList; + } + void addPtrOp(AST::Node& ptrOp); + + DeclaratorAST* subDeclarator() + { + return m_subDeclarator.get(); + } + void setSubDeclarator(AUTO_PTR& subDeclarator); + + NameAST* declaratorId() + { + return m_declaratorId.get(); + } + void setDeclaratorId(NameAST::Node& declaratorId); + + AST* bitfieldInitialization() + { + return m_bitfieldInitialization.get(); + } + void setBitfieldInitialization(AST::Node& bitfieldInitialization); + + QList arrayDimensionList() + { + return m_arrayDimensionList; + } + void addArrayDimension(AST::Node& arrayDimension); + + class ParameterDeclarationClauseAST* parameterDeclarationClause() + { + return m_parameterDeclarationClause.get(); + } + void setParameterDeclarationClause(AUTO_PTR& parameterDeclarationClause); + + // ### replace 'constant' with cvQualify + AST* constant() + { + return m_constant.get(); + } + void setConstant(AST::Node& constant); + + GroupAST* exceptionSpecification() + { + return m_exceptionSpecification.get(); + } + void setExceptionSpecification(GroupAST::Node& exceptionSpecification); + +private: + QList m_ptrOpList; + AUTO_PTR m_subDeclarator; + NameAST::Node m_declaratorId; + AST::Node m_bitfieldInitialization; + QList m_arrayDimensionList; + AUTO_PTR m_parameterDeclarationClause; + AST::Node m_constant; + GroupAST::Node m_exceptionSpecification; + +private: + DeclaratorAST(const DeclaratorAST& source); + void operator = (const DeclaratorAST& source); +}; + +class ParameterDeclarationAST: public AST +{ +public: + typedef AUTO_PTR Node; + enum { Type = NodeType_ParameterDeclaration }; + + DECLARE_ALLOC(ParameterDeclarationAST) + +public: + ParameterDeclarationAST(); + + TypeSpecifierAST* typeSpec() + { + return m_typeSpec.get(); + } + void setTypeSpec(TypeSpecifierAST::Node& typeSpec); + + DeclaratorAST* declarator() + { + return m_declarator.get(); + } + void setDeclarator(DeclaratorAST::Node& declarator); + + AST* expression() + { + return m_expression.get(); + } + void setExpression(AST::Node& expression); + + virtual QString text() const; + +private: + TypeSpecifierAST::Node m_typeSpec; + DeclaratorAST::Node m_declarator; + AST::Node m_expression; + +private: + ParameterDeclarationAST(const ParameterDeclarationAST& source); + void operator = (const ParameterDeclarationAST& source); +}; + +class ParameterDeclarationListAST: public AST +{ +public: + typedef AUTO_PTR Node; + enum { Type = NodeType_ParameterDeclarationList }; + + DECLARE_ALLOC(ParameterDeclarationListAST) + +public: + ParameterDeclarationListAST(); + + QList parameterList() + { + return m_parameterList; + } + void addParameter(ParameterDeclarationAST::Node& parameter); + + virtual QString text() const; + +private: + QList m_parameterList; + +private: + ParameterDeclarationListAST(const ParameterDeclarationListAST& source); + void operator = (const ParameterDeclarationListAST& source); +}; + +class ParameterDeclarationClauseAST: public AST +{ +public: + typedef AUTO_PTR Node; + enum { Type = NodeType_ParameterDeclarationClause }; + + DECLARE_ALLOC(ParameterDeclarationClauseAST) + +public: + ParameterDeclarationClauseAST(); + + ParameterDeclarationListAST* parameterDeclarationList() + { + return m_parameterDeclarationList.get(); + } + void setParameterDeclarationList(ParameterDeclarationListAST::Node& parameterDeclarationList); + + AST* ellipsis() + { + return m_ellipsis.get(); + } + void setEllipsis(AST::Node& ellipsis); + + virtual QString text() const; + +private: + ParameterDeclarationListAST::Node m_parameterDeclarationList; + AST::Node m_ellipsis; + +private: + ParameterDeclarationClauseAST(const ParameterDeclarationClauseAST& source); + void operator = (const ParameterDeclarationClauseAST& source); +}; + + +class InitDeclaratorAST: public AST +{ +public: + typedef AUTO_PTR Node; + enum { Type = NodeType_InitDeclarator }; + + DECLARE_ALLOC(InitDeclaratorAST) + +public: + InitDeclaratorAST(); + + DeclaratorAST* declarator() + { + return m_declarator.get(); + } + void setDeclarator(DeclaratorAST::Node& declarator); + + AST* initializer() + { + return m_initializer.get(); + } + void setInitializer(AST::Node& initializer); + +private: + DeclaratorAST::Node m_declarator; + AST::Node m_initializer; + +private: + InitDeclaratorAST(const InitDeclaratorAST& source); + void operator = (const InitDeclaratorAST& source); +}; + +class InitDeclaratorListAST: public AST +{ +public: + typedef AUTO_PTR Node; + enum { Type = NodeType_InitDeclaratorList }; + + DECLARE_ALLOC(InitDeclaratorListAST) + +public: + InitDeclaratorListAST(); + + QList initDeclaratorList() + { + return m_initDeclaratorList; + } + void addInitDeclarator(InitDeclaratorAST::Node& decl); + +private: + QList m_initDeclaratorList; + +private: + InitDeclaratorListAST(const InitDeclaratorListAST& source); + void operator = (const InitDeclaratorListAST& source); +}; + +class TypedefAST: public DeclarationAST +{ +public: + typedef AUTO_PTR Node; + enum { Type = NodeType_Typedef }; + + DECLARE_ALLOC(TypedefAST) + +public: + TypedefAST(); + + TypeSpecifierAST* typeSpec() + { + return m_typeSpec.get(); + } + void setTypeSpec(TypeSpecifierAST::Node& typeSpec); + + InitDeclaratorListAST* initDeclaratorList() + { + return m_initDeclaratorList.get(); + } + void setInitDeclaratorList(InitDeclaratorListAST::Node& initDeclaratorList); + +private: + TypeSpecifierAST::Node m_typeSpec; + InitDeclaratorListAST::Node m_initDeclaratorList; + +private: + TypedefAST(const TypedefAST& source); + void operator = (const TypedefAST& source); +}; + +class TemplateParameterAST: public AST +{ +public: + typedef AUTO_PTR Node; + enum { Type = NodeType_TemplateParameter }; + + DECLARE_ALLOC(TemplateParameterAST) + +public: + TemplateParameterAST(); + + TypeParameterAST* typeParameter() + { + return m_typeParameter.get(); + } + void setTypeParameter(TypeParameterAST::Node& typeParameter); + + ParameterDeclarationAST* typeValueParameter() + { + return m_typeValueParameter.get(); + } + void setTypeValueParameter(ParameterDeclarationAST::Node& typeValueParameter); + +private: + TypeParameterAST::Node m_typeParameter; + ParameterDeclarationAST::Node m_typeValueParameter; + +private: + TemplateParameterAST(const TemplateParameterAST& source); + void operator = (const TemplateParameterAST& source); +}; + +class TemplateParameterListAST: public AST +{ +public: + typedef AUTO_PTR Node; + enum { Type = NodeType_TemplateParameterList }; + + DECLARE_ALLOC(TemplateParameterListAST) + +public: + TemplateParameterListAST(); + + QList templateParameterList() + { + return m_templateParameterList; + } + void addTemplateParameter(TemplateParameterAST::Node& templateParameter); + +private: + QList m_templateParameterList; + +private: + TemplateParameterListAST(const TemplateParameterListAST& source); + void operator = (const TemplateParameterListAST& source); +}; + +class TemplateDeclarationAST: public DeclarationAST +{ +public: + typedef AUTO_PTR Node; + enum { Type = NodeType_TemplateDeclaration }; + + DECLARE_ALLOC(TemplateDeclarationAST) + +public: + TemplateDeclarationAST(); + + AST* exported() + { + return m_exported.get(); + } + void setExported(AST::Node& exported); + + TemplateParameterListAST* templateParameterList() + { + return m_templateParameterList.get(); + } + void setTemplateParameterList(TemplateParameterListAST::Node& templateParameterList); + + DeclarationAST* declaration() + { + return m_declaration.get(); + } + void setDeclaration(DeclarationAST::Node& declaration); + +private: + AST::Node m_exported; + TemplateParameterListAST::Node m_templateParameterList; + DeclarationAST::Node m_declaration; + +private: + TemplateDeclarationAST(const TemplateDeclarationAST& source); + void operator = (const TemplateDeclarationAST& source); +}; + +class SimpleDeclarationAST: public DeclarationAST +{ +public: + typedef AUTO_PTR Node; + enum { Type = NodeType_SimpleDeclaration }; + + DECLARE_ALLOC(SimpleDeclarationAST) + +public: + SimpleDeclarationAST(); + + GroupAST* functionSpecifier() + { + return m_functionSpecifier.get(); + } + void setFunctionSpecifier(GroupAST::Node& functionSpecifier); + + GroupAST* storageSpecifier() + { + return m_storageSpecifier.get(); + } + void setStorageSpecifier(GroupAST::Node& storageSpecifier); + + TypeSpecifierAST* typeSpec() + { + return m_typeSpec.get(); + } + void setTypeSpec(TypeSpecifierAST::Node& typeSpec); + + InitDeclaratorListAST* initDeclaratorList() + { + return m_initDeclaratorList.get(); + } + void setInitDeclaratorList(InitDeclaratorListAST::Node& initDeclaratorList); + + GroupAST* winDeclSpec() + { + return m_winDeclSpec.get(); + } + void setWinDeclSpec(GroupAST::Node& winDeclSpec); + +private: + GroupAST::Node m_functionSpecifier; + GroupAST::Node m_storageSpecifier; + TypeSpecifierAST::Node m_typeSpec; + InitDeclaratorListAST::Node m_initDeclaratorList; + GroupAST::Node m_winDeclSpec; + +private: + SimpleDeclarationAST(const SimpleDeclarationAST& source); + void operator = (const SimpleDeclarationAST& source); +}; + +class StatementAST: public AST +{ +public: + typedef AUTO_PTR Node; + enum { Type = NodeType_Statement }; + + DECLARE_ALLOC(StatementAST) + +public: + StatementAST(); + +private: + StatementAST(const StatementAST& source); + void operator = (const StatementAST& source); +}; + +class ExpressionStatementAST: public StatementAST +{ +public: + typedef AUTO_PTR Node; + enum { Type = NodeType_ExpressionStatement }; + + DECLARE_ALLOC(ExpressionStatementAST) + +public: + ExpressionStatementAST(); + + AST* expression() + { + return m_expression.get(); + } + void setExpression(AST::Node& expression); + +private: + AST::Node m_expression; + +private: + ExpressionStatementAST(const ExpressionStatementAST& source); + void operator = (const ExpressionStatementAST& source); +}; + +class ConditionAST: public AST +{ +public: + typedef AUTO_PTR Node; + enum { Type = NodeType_Condition }; + + DECLARE_ALLOC(ConditionAST) + +public: + ConditionAST(); + + TypeSpecifierAST* typeSpec() + { + return m_typeSpec.get(); + } + void setTypeSpec(TypeSpecifierAST::Node& typeSpec); + + DeclaratorAST* declarator() + { + return m_declarator.get(); + } + void setDeclarator(DeclaratorAST::Node& declarator); + + AST* expression() + { + return m_expression.get(); + } + void setExpression(AST::Node& expression); + +private: + TypeSpecifierAST::Node m_typeSpec; + DeclaratorAST::Node m_declarator; + AST::Node m_expression; + +private: + ConditionAST(const ConditionAST& source); + void operator = (const ConditionAST& source); +}; + +class IfStatementAST: public StatementAST +{ +public: + typedef AUTO_PTR Node; + enum { Type = NodeType_IfStatement }; + + DECLARE_ALLOC(IfStatementAST) + +public: + IfStatementAST(); + + ConditionAST* condition() const + { + return m_condition.get(); + } + void setCondition(ConditionAST::Node& condition); + + StatementAST* statement() + { + return m_statement.get(); + } + void setStatement(StatementAST::Node& statement); + + StatementAST* elseStatement() + { + return m_elseStatement.get(); + } + void setElseStatement(StatementAST::Node& statement); + +private: + ConditionAST::Node m_condition; + StatementAST::Node m_statement; + StatementAST::Node m_elseStatement; + +private: + IfStatementAST(const IfStatementAST& source); + void operator = (const IfStatementAST& source); +}; + +class WhileStatementAST: public StatementAST +{ +public: + typedef AUTO_PTR Node; + enum { Type = NodeType_WhileStatement }; + + DECLARE_ALLOC(WhileStatementAST) + +public: + WhileStatementAST(); + + ConditionAST* condition() const + { + return m_condition.get(); + } + void setCondition(ConditionAST::Node& condition); + + StatementAST* statement() + { + return m_statement.get(); + } + void setStatement(StatementAST::Node& statement); + +private: + ConditionAST::Node m_condition; + StatementAST::Node m_statement; + +private: + WhileStatementAST(const WhileStatementAST& source); + void operator = (const WhileStatementAST& source); +}; + +class DoStatementAST: public StatementAST +{ +public: + typedef AUTO_PTR Node; + enum { Type = NodeType_DoStatement }; + + DECLARE_ALLOC(DoStatementAST) + +public: + DoStatementAST(); + + ConditionAST* condition() const + { + return m_condition.get(); + } + void setCondition(ConditionAST::Node& condition); + + StatementAST* statement() + { + return m_statement.get(); + } + void setStatement(StatementAST::Node& statement); + +private: + ConditionAST::Node m_condition; + StatementAST::Node m_statement; + +private: + DoStatementAST(const DoStatementAST& source); + void operator = (const DoStatementAST& source); +}; + +class ForStatementAST: public StatementAST +{ +public: + typedef AUTO_PTR Node; + enum { Type = NodeType_ForStatement }; + + DECLARE_ALLOC(ForStatementAST) + +public: + ForStatementAST(); + + StatementAST* initStatement() + { + return m_initStatement.get(); + } + void setInitStatement(StatementAST::Node& statement); + + ConditionAST* condition() const + { + return m_condition.get(); + } + void setCondition(ConditionAST::Node& condition); + + AST* expression() const + { + return m_expression.get(); + } + void setExpression(AST::Node& expression); + + StatementAST* statement() + { + return m_statement.get(); + } + void setStatement(StatementAST::Node& statement); + +private: + ConditionAST::Node m_condition; + StatementAST::Node m_initStatement; + StatementAST::Node m_statement; + AST::Node m_expression; + +private: + ForStatementAST(const ForStatementAST& source); + void operator = (const ForStatementAST& source); +}; + +// qt4 [erbsland] +class ForEachStatementAST: public StatementAST +{ +public: + typedef AUTO_PTR Node; + enum { Type = NodeType_ForEachStatement }; + + DECLARE_ALLOC(ForEachStatementAST) + +public: + ForEachStatementAST(); + + StatementAST* initStatement() + { + return m_initStatement.get(); + } + void setInitStatement(StatementAST::Node& statement); + + StatementAST* statement() + { + return m_statement.get(); + } + void setStatement(StatementAST::Node& statement); + + AST* expression() const + { + return m_expression.get(); + } + void setExpression(AST::Node& expression); + +private: + StatementAST::Node m_initStatement; + StatementAST::Node m_statement; + AST::Node m_expression; + +private: + ForEachStatementAST(const ForEachStatementAST& source); + void operator = (const ForEachStatementAST& source); +}; + +class SwitchStatementAST: public StatementAST +{ +public: + typedef AUTO_PTR Node; + enum { Type = NodeType_SwitchStatement }; + + DECLARE_ALLOC(SwitchStatementAST) + +public: + SwitchStatementAST(); + + ConditionAST* condition() const + { + return m_condition.get(); + } + void setCondition(ConditionAST::Node& condition); + + StatementAST* statement() + { + return m_statement.get(); + } + void setStatement(StatementAST::Node& statement); + +private: + ConditionAST::Node m_condition; + StatementAST::Node m_statement; + +private: + SwitchStatementAST(const SwitchStatementAST& source); + void operator = (const SwitchStatementAST& source); +}; + +class StatementListAST: public StatementAST +{ +public: + typedef AUTO_PTR Node; + enum { Type = NodeType_StatementList }; + + DECLARE_ALLOC(StatementListAST) + +public: + StatementListAST(); + + QList statementList() + { + return m_statementList; + } + void addStatement(StatementAST::Node& statement); + +private: + QList m_statementList; + +private: + StatementListAST(const StatementListAST& source); + void operator = (const StatementListAST& source); +}; + +class CatchStatementAST: public StatementAST +{ +public: + typedef AUTO_PTR Node; + enum { Type = NodeType_CatchStatement }; + + DECLARE_ALLOC(CatchStatementAST) + +public: + CatchStatementAST(); + + ConditionAST* condition() const + { + return m_condition.get(); + } + void setCondition(ConditionAST::Node& condition); + + StatementAST* statement() + { + return m_statement.get(); + } + void setStatement(StatementAST::Node& statement); + +private: + ConditionAST::Node m_condition; + StatementAST::Node m_statement; + +private: + CatchStatementAST(const CatchStatementAST& source); + void operator = (const CatchStatementAST& source); +}; + +class CatchStatementListAST: public StatementAST +{ +public: + typedef AUTO_PTR Node; + enum { Type = NodeType_CatchStatementList }; + + DECLARE_ALLOC(CatchStatementListAST) + +public: + CatchStatementListAST(); + + QList statementList() + { + return m_statementList; + } + void addStatement(CatchStatementAST::Node& statement); + +private: + QList m_statementList; + +private: + CatchStatementListAST(const CatchStatementListAST& source); + void operator = (const CatchStatementListAST& source); +}; + +class TryBlockStatementAST: public StatementAST +{ +public: + typedef AUTO_PTR Node; + enum { Type = NodeType_TryBlockStatement }; + + DECLARE_ALLOC(TryBlockStatementAST) + +public: + TryBlockStatementAST(); + + StatementAST* statement() + { + return m_statement.get(); + } + void setStatement(StatementAST::Node& statement); + + CatchStatementListAST* catchStatementList() + { + return m_catchStatementList.get(); + } + void setCatchStatementList(CatchStatementListAST::Node& statementList); + +private: + StatementAST::Node m_statement; + CatchStatementListAST::Node m_catchStatementList; + +private: + TryBlockStatementAST(const TryBlockStatementAST& source); + void operator = (const TryBlockStatementAST& source); +}; + +class DeclarationStatementAST: public StatementAST +{ +public: + typedef AUTO_PTR Node; + enum { Type = NodeType_DeclarationStatement }; + + DECLARE_ALLOC(DeclarationStatementAST) + +public: + DeclarationStatementAST(); + + DeclarationAST* declaration() + { + return m_declaration.get(); + } + void setDeclaration(DeclarationAST::Node& declaration); + +private: + DeclarationAST::Node m_declaration; + +private: + DeclarationStatementAST(const DeclarationStatementAST& source); + void operator = (const DeclarationStatementAST& source); +}; + +class FunctionDefinitionAST: public DeclarationAST +{ +public: + typedef AUTO_PTR Node; + enum { Type = NodeType_FunctionDefinition }; + + DECLARE_ALLOC(FunctionDefinitionAST) + +public: + FunctionDefinitionAST(); + + GroupAST* functionSpecifier() + { + return m_functionSpecifier.get(); + } + void setFunctionSpecifier(GroupAST::Node& functionSpecifier); + + GroupAST* storageSpecifier() + { + return m_storageSpecifier.get(); + } + void setStorageSpecifier(GroupAST::Node& storageSpecifier); + + TypeSpecifierAST* typeSpec() + { + return m_typeSpec.get(); + } + void setTypeSpec(TypeSpecifierAST::Node& typeSpec); + + InitDeclaratorAST* initDeclarator() + { + return m_initDeclarator.get(); + } + void setInitDeclarator(InitDeclaratorAST::Node& initDeclarator); + + StatementListAST* functionBody() + { + return m_functionBody.get(); + } + void setFunctionBody(StatementListAST::Node& functionBody); + + GroupAST* winDeclSpec() + { + return m_winDeclSpec.get(); + } + void setWinDeclSpec(GroupAST::Node& winDeclSpec); + +private: + GroupAST::Node m_functionSpecifier; + GroupAST::Node m_storageSpecifier; + TypeSpecifierAST::Node m_typeSpec; + InitDeclaratorAST::Node m_initDeclarator; + StatementListAST::Node m_functionBody; + GroupAST::Node m_winDeclSpec; + +private: + FunctionDefinitionAST(const FunctionDefinitionAST& source); + void operator = (const FunctionDefinitionAST& source); +}; + + +class TranslationUnitAST: public AST, public KShared +{ +public: + typedef KSharedPtr Node; + enum { Type = NodeType_TranslationUnit }; + + DECLARE_ALLOC(TranslationUnitAST) + +public: + TranslationUnitAST(); + + void addDeclaration(DeclarationAST::Node& ast); + QList declarationList() + { + return m_declarationList; + } + +private: + QList m_declarationList; + +private: + TranslationUnitAST(const TranslationUnitAST& source); + void operator = (const TranslationUnitAST& source); +}; + +#endif diff -Nru umbrello-4.12.3/lib/cppparser/ast_utils.cpp umbrello-4.12.90/lib/cppparser/ast_utils.cpp --- umbrello-4.12.3/lib/cppparser/ast_utils.cpp 1970-01-01 00:00:00.000000000 +0000 +++ umbrello-4.12.90/lib/cppparser/ast_utils.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -0,0 +1,129 @@ +/*************************************************************************** + * Copyright (C) 2002 by Roberto Raggi * + * roberto@kdevelop.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "ast_utils.h" + +#include "ast.h" +#include "debug_utils.h" + +#include +#include + +#include + +void scopeOfNode(AST* ast, QStringList& scope) +{ + if (!ast) + return; + + if (ast->parent()) + scopeOfNode(ast->parent(), scope); + + QString s; + switch (ast->nodeType()) { + case NodeType_ClassSpecifier: + if (((ClassSpecifierAST*)ast)->name()) { + s = ((ClassSpecifierAST*)ast)->name()->text(); + s = s.isEmpty() ? QString::fromLatin1("") : s; + scope.push_back(s); + } + break; + + case NodeType_Namespace: { + AST* namespaceName = ((NamespaceAST*)ast)->namespaceName(); + s = namespaceName ? namespaceName->text() : QString::fromLatin1(""); + scope.push_back(s); + } + break; + + case NodeType_FunctionDefinition: { + FunctionDefinitionAST* funDef = static_cast(ast); + DeclaratorAST* d = funDef->initDeclarator()->declarator(); + + // hotfix for bug #68726 + if (!d->declaratorId()) + break; + + QList l = d->declaratorId()->classOrNamespaceNameList(); + for (int i = 0; i < l.size(); ++i) { + AST* name = l.at(i)->name(); + scope.push_back(name->text()); + } + } + break; + + default: + break; + } +} + +QString typeSpecToString(TypeSpecifierAST* typeSpec) /// @todo remove +{ + if (!typeSpec) + return QString(); + + return typeSpec->text().replace(QRegExp(" :: "), "::"); +} + +QString declaratorToString(DeclaratorAST* declarator, const QString& scope, bool skipPtrOp) +{ + if (!declarator) + return QString(); + + QString text; + + if (!skipPtrOp) { + QList ptrOpList = declarator->ptrOpList(); + for (int i = 0; i < ptrOpList.size(); ++i) { + text += ptrOpList.at(i)->text(); + } + text += ' '; + } + + text += scope; + + if (declarator->subDeclarator()) + text += QString::fromLatin1("(") + declaratorToString(declarator->subDeclarator()) + QString::fromLatin1(")"); + + if (declarator->declaratorId()) + text += declarator->declaratorId()->text(); + + QList arrays = declarator->arrayDimensionList(); + for (int i = 0; i < arrays.size(); ++i) { + text += "[]"; + } + + if (declarator->parameterDeclarationClause()) { + text += '('; + + ParameterDeclarationListAST* l = declarator->parameterDeclarationClause()->parameterDeclarationList(); + if (l != 0) { + QList params = l->parameterList(); + for (int i = 0; i < params.size(); ++i) { + QString type = typeSpecToString(params.at(i)->typeSpec()); + text += type; + if (!type.isEmpty()) + text += ' '; + text += declaratorToString(params.at(i)->declarator()); + + if (params.at(i)) + text += ", "; + } + } + + text += ')'; + + if (declarator->constant() != 0) + text += " const"; + } + + return text.replace(QRegExp(" :: "), "::").simplified(); +} diff -Nru umbrello-4.12.3/lib/cppparser/ast_utils.h umbrello-4.12.90/lib/cppparser/ast_utils.h --- umbrello-4.12.3/lib/cppparser/ast_utils.h 1970-01-01 00:00:00.000000000 +0000 +++ umbrello-4.12.90/lib/cppparser/ast_utils.h 2014-03-05 15:04:09.000000000 +0000 @@ -0,0 +1,31 @@ +/*************************************************************************** + * Copyright (C) 2002 by Roberto Raggi * + * roberto@kdevelop.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef AST_UTILS_H +#define AST_UTILS_H + +#include + +class AST; +class DeclaratorAST; +class TypeSpecifierAST; +class QStringList; + +namespace KTextEditor +{ +class EditInterface; +} + +void scopeOfNode(AST* ast, QStringList&); +QString typeSpecToString(TypeSpecifierAST* typeSpec); +QString declaratorToString(DeclaratorAST* declarator, const QString& scope = QString(), bool skipPtrOp=false); + +#endif // AST_UTILS_H diff -Nru umbrello-4.12.3/lib/cppparser/cachemanager.cpp umbrello-4.12.90/lib/cppparser/cachemanager.cpp --- umbrello-4.12.3/lib/cppparser/cachemanager.cpp 1970-01-01 00:00:00.000000000 +0000 +++ umbrello-4.12.90/lib/cppparser/cachemanager.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -0,0 +1,100 @@ +/*************************************************************************** + copyright : (C) 2006 by David Nolden + email : david.nolden.kdevelop@art-master.de +***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "cachemanager.h" +#include + +void CacheNode::access() const +{ + m_manager->access(this); +} + +void CacheManager::remove(const CacheNode* node) +{ + m_set.erase(node); +} + +void CacheManager::add(const CacheNode* node) +{ + m_set.insert(node); +} + +CacheNode::CacheNode(Manager* manager) : m_manager(manager), m_value(manager->currentMax()) //initialize m_value with the current maximum, so the new node has a chance even in a cache full of high-rated nodes +{ + m_manager->add(this); +} + +CacheNode::~CacheNode() +{ + m_manager->remove(this); +}; + +void CacheManager::restart(uint normalizeby) +{ + m_currentFrame = 1; + m_currentMax = 1; + SetType oldSet = m_set; + m_set = SetType(); + for (SetType::iterator it = oldSet.begin(); it != oldSet.end(); ++it) { + uint newValue = (*it)->value() / (normalizeby / 1000); + if (newValue > m_currentMax) m_currentMax = newValue; + (*it)->setValue(newValue); ///This way not all information is discarded + m_set.insert(*it); + } +} + +void CacheManager::access(const CacheNode* node) +{ + static const uint limit = (std::numeric_limits::max() / 3)*2; + m_set.erase(node); + node->setValue(m_currentMax+1); + m_set.insert(node); + if (node->value() > m_currentMax) + m_currentMax = node->value(); + if (node->value() > limit) + restart(node->value()); +} + +void CacheManager::setMaxNodes (int maxNodes) +{ + m_maxNodes = maxNodes; + increaseFrame(); +} + +void CacheManager::increaseFrame() +{ + m_currentFrame ++; + if (m_set.size() > m_maxNodes) { + //kdDebug(9007) << "CacheManager: Have " << m_set.size() << " nodes, maximum is " << m_maxNodes << ", erasing." << endl; + int mustErase = m_set.size() - m_maxNodes; + while (!m_set.empty() && mustErase != 0) { + --mustErase; + SetType::iterator it = m_set.begin(); + erase(*it); + } + //kdDebug(9007) << "CacheManager: Have " << m_set.size() << " nodes after erasing." << endl; + } +} + +void CacheManager::removeLowerHalf() +{ + int maxNodes = m_maxNodes; + setMaxNodes(m_set.size() / 2); + setMaxNodes(maxNodes); +} + +void CacheManager::saveMemory() +{ + removeLowerHalf(); +} diff -Nru umbrello-4.12.3/lib/cppparser/cachemanager.h umbrello-4.12.90/lib/cppparser/cachemanager.h --- umbrello-4.12.3/lib/cppparser/cachemanager.h 1970-01-01 00:00:00.000000000 +0000 +++ umbrello-4.12.90/lib/cppparser/cachemanager.h 2014-03-05 15:04:09.000000000 +0000 @@ -0,0 +1,113 @@ + +/*************************************************************************** + copyright : (C) 2006 by David Nolden + email : david.nolden.kdevelop@art-master.de +***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef CACHEMANAGER_H +#define CACHEMANAGER_H +#include +#include +#include + +class CacheManager; + + +class CacheNode +{ + typedef CacheManager Manager; +public: + CacheNode(Manager* manager); + + virtual ~CacheNode(); + + void access() const; + + inline uint value() const + { + return m_value; + } + + inline void setValue(const uint v) const + { + m_value = v; + } + + inline void addValue(const uint diff) const + { + m_value += diff; + } + +private: + Manager* m_manager; + mutable uint m_value; //This value stands for the priority of the node(higher is better) +}; + +class CacheNodeCompare +{ +public: + bool operator() (const CacheNode* lhs, const CacheNode* rhs) const + { + if (lhs->value() != rhs->value()) + return lhs->value() < rhs->value(); + else + return lhs < rhs; //To be able to identify nodes precisely + } +}; + + +class CacheManager +{ + typedef std::set< const CacheNode*, CacheNodeCompare > SetType; +public: + CacheManager(int maxNodes = 1000) : m_currentFrame(1), m_maxNodes(maxNodes), m_currentMax(1) + { + }; + virtual ~CacheManager() {}; + + inline int currentFrame() const + { + return m_currentFrame; + } + + void access(const CacheNode* node); + + ///Can be used from outside to set the maximum count of nodes to keep. + void setMaxNodes (int maxNodes); + + void increaseFrame(); + + ///Can be used on a regular basis(time-triggered) to save memory: Removes half of all triggered + void removeLowerHalf(); + + virtual void saveMemory(); + + int currentMax() const + { + return m_currentMax; + } + + ///This triggered function should erase the given node. + virtual void erase(const CacheNode* node) = 0; +private: + void restart(uint normalizeby); + friend class CacheNode; + void remove(const CacheNode* node); + void add(const CacheNode* node); + int m_currentFrame; + uint m_maxNodes; + uint m_currentMax; + SetType m_set; +}; + + +#endif diff -Nru umbrello-4.12.3/lib/cppparser/driver.cpp umbrello-4.12.90/lib/cppparser/driver.cpp --- umbrello-4.12.3/lib/cppparser/driver.cpp 1970-01-01 00:00:00.000000000 +0000 +++ umbrello-4.12.90/lib/cppparser/driver.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -0,0 +1,1035 @@ +/* This file is part of KDevelop + Copyright (C) 2002, 2003 Roberto Raggi + Copyright (C) 2006 David Nolden + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#define CACHELEXER + +#include "driver.h" +#include "lexer.h" +#include "parser.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + +// void Macro::read(QDataStream& stream) { +// stream >> m_idHashValid; +// stream >> m_valueHashValid; +// stream >> m_idHash; +// stream >> m_valueHash; +// stream >> m_name; +// stream >> m_body; +// stream >> m_fileName; +// stream >> m_hasArguments; +// stream >> m_argumentList; +// } +// +// void Macro::write(QDataStream& stream) const { +// stream << m_idHashValid; +// stream << m_valueHashValid; +// stream << m_idHash; +// stream << m_valueHash; +// stream << m_name; +// stream << m_body; +// stream << m_fileName; +// stream << m_hasArguments; +// stream << m_argumentList; +// } + + +class IntIncreaser +{ +public: + IntIncreaser(int& i) : m_i(i) + { + ++m_i; + } + ~IntIncreaser() + { + --m_i; + } +private: + int& m_i; +}; + +class DefaultSourceProvider: public SourceProvider +{ +public: + DefaultSourceProvider() {} + + virtual QString contents(const QString& fileName) + { + QString source; + + QFile f(fileName); + if (f.open(QIODevice::ReadOnly)) { + QTextStream s(&f); + source = s.readAll(); + f.close(); + } + return source; + } + + virtual bool isModified(const QString& fileName) + { + Q_UNUSED(fileName); + return true; + } + +private: + DefaultSourceProvider(const DefaultSourceProvider& source); + void operator = (const DefaultSourceProvider& source); +}; + + +Driver::Driver() + : depresolv(0), lexer(0), m_lexerCache(this), m_dependenceDepth(0), m_maxDependenceDepth(20) +{ + m_sourceProvider = new DefaultSourceProvider(); +} + +Driver::~Driver() +{ + reset(); + delete m_sourceProvider; +} + +void Driver::setMaxDependenceDepth(int depth) +{ + m_maxDependenceDepth = depth; +} + +SourceProvider* Driver::sourceProvider() +{ + return m_sourceProvider; +} + +void Driver::setSourceProvider(SourceProvider* sourceProvider) +{ + delete m_sourceProvider; + m_sourceProvider = sourceProvider; +} + +void Driver::reset() +{ + m_lexerCache.clear(); + m_dependences.clear(); + m_macros.clear(); + m_problems.clear(); + m_includePaths.clear(); + + while (m_parsedUnits.size()) { + //TranslationUnitAST* unit = **m_parsedUnits.begin(); + m_parsedUnits.erase(m_parsedUnits.begin()); + //delete(unit); + } +} + +QStringList Driver::getCustomIncludePath(const QString&) +{ + return includePaths(); +} + +void Driver::remove +(const QString & fileName) +{ + m_dependences.remove(fileName); + m_problems.remove(fileName); + if (!isResolveDependencesEnabled()) + removeAllMacrosInFile(fileName); + + QMap::Iterator it = m_parsedUnits.find(fileName); + if (it != m_parsedUnits.end()) { + //TranslationUnitAST * unit = **it; + m_parsedUnits.erase(it); + //delete(unit); + } +} + +void Driver::removeAllMacrosInFile(const QString& fileName) +{ + MacroMap::iterator it = m_macros.begin(); + while (it != m_macros.end()) { + Macro m = (*it).second; + if (m.fileName() == fileName) { + m_macros.erase(it++); + } else { + ++it; + } + } +} + +void Driver::usingString(const HashedString& str) +{ +#ifdef CACHELEXER + if (m_currentLexerCache) { + m_currentLexerCache->addString(m_lexerCache.unifyString(str)); + } +#endif +} + +bool Driver::hasMacro(const HashedString& name) +{ + std::pair< MacroMap::const_iterator, MacroMap::const_iterator > range = m_macros.equal_range(name); + if (range.first == range.second) { + return false; + } else { + const Macro& m((*(--range.second)).second); + if (m.isUndef()) + return false; + else + return true; + } + return false; +} + +QString deepCopy(const QString& str) +{ + return str; + //return str.ascii(); +} + +const Macro& Driver::macro(const HashedString& name) const +{ + std::pair< MacroMap::const_iterator, MacroMap::const_iterator > range = m_macros.equal_range(name); + if (range.first == range.second) { + return (*const_cast(m_macros).insert(std::make_pair(deepCopy(name.str()), Macro()))).second; ///Since we need to return a reference, there's no other way. + } else { + return (*(--range.second)).second; + } +} +Macro& Driver::macro(const HashedString& name) +{ + std::pair< MacroMap::iterator, MacroMap::iterator > range = m_macros.equal_range(name); + if (range.first == range.second) { + return (*m_macros.insert(std::make_pair(deepCopy(name.str()), Macro()))).second; + } else { + return (*(--range.second)).second; + } +} + +void Driver::addMacro(const Macro & macro) +{ + std::pair< MacroMap::iterator, MacroMap::iterator > range = m_macros.equal_range(macro.name()); + + if (range.first == range.second) { + m_macros.insert(std::make_pair(deepCopy(macro.name()), macro)); + } else { + ///Insert behind the other macros + m_macros.insert(range.second, std::make_pair(deepCopy(macro.name()), macro)); + Macro cp = this->macro(macro.name()); + assert(macro == cp); + } + +#ifdef CACHELEXER + if (m_currentLexerCache) + m_currentLexerCache->addDefinedMacro(macro); +#endif +} + +void Driver::removeMacro(const HashedString& macroName) +{ + std::pair< MacroMap::iterator, MacroMap::iterator > range = m_macros.equal_range(macroName); + if (range.first != range.second) { + m_macros.erase(--range.second); + } +} + +ParsedFilePointer Driver::takeTranslationUnit(const QString& fileName) +{ + QMap::const_iterator it = m_parsedUnits.constFind(fileName); + ParsedFilePointer unit(*it); + m_parsedUnits[ fileName ] = 0; + return unit; +} + +void Driver::takeTranslationUnit(const ParsedFile& file) +{ + m_parsedUnits[ file.fileName() ] = 0; +} + +ParsedFilePointer Driver::translationUnit(const QString& fileName) const +{ + QMap::const_iterator it = m_parsedUnits.constFind(fileName); + if (it != m_parsedUnits.constEnd()) + return it.value(); + else + return ParsedFilePointer(); +} + +class Driver::ParseHelper +{ +public: + ParseHelper(const QString& fileName, bool force, Driver* driver, bool reportMessages = true, QString includedFrom = QString()) : m_wasReset(false), m_fileName(fileName), m_previousFileName(driver->m_currentFileName), m_previousLexer(driver->lexer), m_previousParsedFile(driver->m_currentParsedFile), m_previousCachedLexedFile(driver->m_currentLexerCache), m_force(force), m_driver(driver), m_lex(m_driver) + { + QFileInfo fileInfo(fileName); + m_driver->m_currentParsedFile = new ParsedFile(fileName, fileInfo.lastModified()); + if (!includedFrom.isEmpty()) + m_driver->m_currentParsedFile->setIncludedFrom(includedFrom); +#ifdef CACHELEXER + m_driver->m_currentLexerCache = new CachedLexedFile(fileName, &m_driver->m_lexerCache); +#endif + m_absoluteFilePath = fileInfo.absoluteFilePath(); + + QMap::Iterator it = m_driver->m_parsedUnits.find(m_absoluteFilePath); + + if (force && it != m_driver->m_parsedUnits.end()) { + m_driver->takeTranslationUnit(m_absoluteFilePath); + } else if (it != m_driver->m_parsedUnits.end() && *it != (ParsedFilePointer)0) { + // file already processed + return ; + } + + CachedLexedFilePointer lexedFileP = m_driver->m_lexerCache.lexedFile(HashedString(fileName)); + + m_driver->m_dependences.remove(fileName); + m_driver->m_problems.remove(fileName); + + driver->m_currentFileName = fileName; + + m_driver->lexer = &m_lex; + m_driver->setupLexer(&m_lex); + + m_lex.setReportMessages(reportMessages); + + //kdDebug(9007) << "lexing file " << fileName << endl; + m_lex.setSource(m_driver->sourceProvider() ->contents(fileName)); + if (m_previousCachedLexedFile) + m_previousCachedLexedFile->merge(*m_driver->m_currentLexerCache); + else + m_driver->findOrInsertProblemList(m_driver->m_currentMasterFileName) += m_driver->m_currentLexerCache->problems(); + + if (!lexedFileP && m_previousParsedFile) //only add the new cache-instance if a fitting isn't already stored, and if this file was included by another one. + m_driver->m_lexerCache.addLexedFile(m_driver->m_currentLexerCache); + + //Copy the recursive include-files into the ParsedFile + m_driver->m_currentParsedFile->addIncludeFiles(m_driver->m_currentLexerCache->includeFiles()); + m_driver->m_currentParsedFile->setSkippedLines(m_lex.skippedLines()); + } + + void parse() + { + QString oldMasterFileName = m_driver->m_currentMasterFileName; //Change the master-file so problems will be reported correctly + m_driver->m_currentMasterFileName = m_absoluteFilePath; + + CachedLexedFilePointer lf = m_driver->m_currentLexerCache; //Set the lexer-cache to zero, so the problems registered through addProblem go directly into the file + m_driver->m_currentLexerCache = 0; + + Parser parser(m_driver, m_driver->lexer); + m_driver->setupParser(&parser); + + TranslationUnitAST::Node unit; + parser.parseTranslationUnit(unit); + m_driver->m_currentParsedFile->setTranslationUnit(unit); + m_driver->m_parsedUnits.insert(m_fileName, m_driver->m_currentParsedFile); + m_driver->fileParsed(*m_driver->m_currentParsedFile); + + m_driver->m_currentLexerCache = lf; + + m_driver->m_currentMasterFileName = oldMasterFileName; + } + + ParsedFilePointer parsedFile() const + { + return m_driver->m_currentParsedFile; + } + + void reset() + { + if (!m_wasReset) { + m_driver->m_currentFileName = m_previousFileName; + m_driver->lexer = m_previousLexer; + m_driver->m_currentParsedFile = m_previousParsedFile; + m_driver->m_currentLexerCache = m_previousCachedLexedFile; + m_wasReset = true; + } + } + + ~ParseHelper() + { + reset(); + } + + +private: + bool m_wasReset; + QString m_fileName; + QString m_absoluteFilePath; + QString m_previousFileName; + Lexer* m_previousLexer; + ParsedFilePointer m_previousParsedFile; + CachedLexedFilePointer m_previousCachedLexedFile; + bool m_force; + Driver* m_driver; + Lexer m_lex; +}; + + +void Driver::addDependence(const QString & fileName, const Dependence & dep) +{ + + // this can happen if the parser was invoked on a snippet of text and not a file + if (fileName.isEmpty() || !m_currentParsedFile) + return; + + //@todo prevent cyclic dependency-loops + QFileInfo fileInfo(dep.first); + QString fn = fileInfo.absoluteFilePath(); + + if (!depresolv) { + findOrInsertDependenceList(fileName).insert(fn, dep); + m_currentParsedFile->addIncludeFile(dep.first, ParsedFilePointer(), dep.second == Dep_Local); + return ; + } + + QString file = findIncludeFile(dep); + + findOrInsertDependenceList(fileName).insert(file, dep); + m_currentParsedFile->addIncludeFile(file, ParsedFilePointer(), dep.second == Dep_Local); + + if (!QFile::exists(file)) { + Problem p(i18n("Could not find include file %1").arg(dep.first), + lexer ? lexer->currentLine() : -1, + lexer ? lexer->currentColumn() : -1, Problem::Level_Warning); + addProblem(fileName, p); + return ; + } + + if (m_currentLexerCache) + m_currentLexerCache->addIncludeFile(file, QDateTime()); ///The time will be overwritten in CachedLexedFile::merge(...) + + /**What should be done: + * 1. Lex the file to get all the macros etc. + * 2. TODO: Check what previously set macros the file was affected by, and compare those macros to any previously parsed instances of this file. + * 2.1 If there is a parse-instance of the file where all macros that played a role had the same values, we do not need to reparse this file. + * 2.2 If there is no such fitting instance, the file needs to be parsed and put to the code-model. + * + * It'll be necessary to have multiple versions of one file in the code-model. + */ + + IntIncreaser i(m_dependenceDepth); + if (m_dependenceDepth > m_maxDependenceDepth) { + //kdDebug(9007) << "maximum dependence-depth of " << m_maxDependenceDepth << " was reached, " << fileName << " will not be processed" << endl; + return; + } + + CachedLexedFilePointer lexedFileP = m_lexerCache.lexedFile(HashedString(file)); + if (lexedFileP) { + CachedLexedFile& lexedFile(*lexedFileP); + m_currentLexerCache->merge(lexedFile); //The ParseHelper will will copy the include-files into the result later + for (MacroSet::Macros::const_iterator it = lexedFile.definedMacros().macros().begin(); it != lexedFile.definedMacros().macros().end(); ++it) { + addMacro((*it)); + } + ///@todo fill usingMacro(...) + return; + } + + ParseHelper h(file, true, this, false, m_currentMasterFileName); + + /*if (m_parsedUnits.find(file) != m_parsedUnits.end()) + return;*/ + + if (shouldParseIncludedFile(m_currentParsedFile)) ///Until the ParseHelper is destroyed, m_currentParsedFile will stay the included file + h.parse(); +} + +void Driver::addProblem(const QString & fileName, const Problem & problem) +{ + Problem p(problem); + p.setFileName(fileName); + + if (m_currentLexerCache) + m_currentLexerCache->addProblem(p); + else + findOrInsertProblemList(m_currentMasterFileName).append(problem); +} + +QMap< QString, Dependence >& Driver::findOrInsertDependenceList(const QString & fileName) +{ + QMap >::Iterator it = m_dependences.find(fileName); + if (it != m_dependences.end()) + return *it; + + QMap l; + m_dependences.insert(deepCopy(fileName), l); + return m_dependences[ fileName ]; +} + +QList < Problem >& Driver::findOrInsertProblemList(const QString & fileName) +{ + QMap >::Iterator it = m_problems.find(fileName); + if (it != m_problems.end()) + return *it; + + QList l; + m_problems.insert(fileName, l); + return m_problems[ fileName ]; +} + +QMap< QString, Dependence > Driver::dependences(const QString & fileName) const +{ + QMap >::ConstIterator it = m_dependences.find(fileName); + if (it != m_dependences.end()) + return *it; + return QMap(); +} + +const Driver::MacroMap& Driver::macros() const +{ + return m_macros; +} + +void Driver::insertMacros(const MacroSet& macros) +{ + for (MacroSet::Macros::const_iterator it = macros.m_usedMacros.begin(); it != macros.m_usedMacros.end(); ++it) { + addMacro(*it); + } +} + +QList < Problem > Driver::problems(const QString & fileName) const +{ + QMap >::ConstIterator it = m_problems.find(fileName); + if (it != m_problems.end()) + return *it; + return QList(); +} + +void Driver::clearMacros() +{ + m_macros.clear(); +} + +void Driver::clearParsedMacros() +{ + //Keep global macros + for (MacroMap::iterator it = m_macros.begin(); it != m_macros.end();) { + if (!(*it).second.fileName().isEmpty()) { + m_macros.erase(it++); + } else { + ++it; + } + } +} + +bool Driver::parseFile(const QString& fileName, bool onlyPreProcess, bool force , bool macrosGlobal) +{ + QString oldMasterFileName = m_currentMasterFileName; + m_currentMasterFileName = fileName; + +//if(isResolveDependencesEnabled()) + clearParsedMacros(); ///Since everything will be re-lexed, we do not need any old macros + + m_lexerCache.increaseFrame(); + + //Remove the problems now instead of in ParseHelper, because this way the problems reported by getCustomIncludePath(...) will not be discarded + m_problems.remove(fileName); + + QStringList oldIncludePaths = m_includePaths; + m_includePaths = getCustomIncludePath(fileName); + + ParseHelper p(fileName, force, this); + if (!onlyPreProcess) { + p.parse(); + } + if (macrosGlobal) { + for (MacroMap::iterator it = m_macros.begin(); it != m_macros.end(); ++it) { + if ((*it).second.fileName() == fileName) { + (*it).second.setFileName(QString()); + } + } + } + + m_includePaths = oldIncludePaths; + m_currentMasterFileName = oldMasterFileName; + return true; +} + +void Driver::setupLexer(Lexer * lexer) +{ + // stl + lexer->addSkipWord("__STL_BEGIN_NAMESPACE"); + lexer->addSkipWord("__STL_END_NAMESPACE"); + lexer->addSkipWord("__STL_BEGIN_RELOPS_NAMESPACE"); + lexer->addSkipWord("__STL_END_RELOPS_NAMESPACE"); + lexer->addSkipWord("__STL_TEMPLATE_NULL"); + lexer->addSkipWord("__STL_TRY"); + lexer->addSkipWord("__STL_UNWIND"); + lexer->addSkipWord("__STL_NOTHROW"); + lexer->addSkipWord("__STL_NULL_TMPL_ARGS"); + lexer->addSkipWord("__STL_UNWIND", SkipWordAndArguments); + lexer->addSkipWord("__GC_CONST"); + lexer->addSkipWord("__HASH_ALLOC_INIT", SkipWordAndArguments); + lexer->addSkipWord("__STL_DEFAULT_ALLOCATOR", SkipWordAndArguments, "T"); + lexer->addSkipWord("__STL_MUTEX_INITIALIZER"); + lexer->addSkipWord("__STL_NULL_TMPL_ARGS"); + + // antlr + lexer->addSkipWord("ANTLR_BEGIN_NAMESPACE", SkipWordAndArguments); + lexer->addSkipWord("ANTLR_USE_NAMESPACE", SkipWordAndArguments); + lexer->addSkipWord("ANTLR_USING_NAMESPACE", SkipWordAndArguments); + lexer->addSkipWord("ANTLR_END_NAMESPACE"); + lexer->addSkipWord("ANTLR_C_USING", SkipWordAndArguments); + lexer->addSkipWord("ANTLR_API"); + + // gnu + lexer->addSkipWord("__extension__", SkipWordAndArguments); + lexer->addSkipWord("__attribute__", SkipWordAndArguments); + lexer->addSkipWord("__BEGIN_DECLS"); + lexer->addSkipWord("__END_DECLS"); + lexer->addSkipWord("__THROW"); + lexer->addSkipWord("__restrict"); + lexer->addSkipWord("__restrict__"); + lexer->addSkipWord("__attribute_pure__"); + lexer->addSkipWord("__attribute_malloc__"); + lexer->addSkipWord("__attribute_format_strfmon__"); + lexer->addSkipWord("__asm__", SkipWordAndArguments); + lexer->addSkipWord("__devinit"); + lexer->addSkipWord("__devinit__"); + lexer->addSkipWord("__init"); + lexer->addSkipWord("__init__"); + lexer->addSkipWord("__signed"); + lexer->addSkipWord("__signed__"); + lexer->addSkipWord("__unsigned"); + lexer->addSkipWord("__unsigned__"); + lexer->addSkipWord("asmlinkage"); + lexer->addSkipWord("____cacheline_aligned"); + lexer->addSkipWord("__glibcpp_class_requires", SkipWordAndArguments); + lexer->addSkipWord("__glibcpp_class2_requires", SkipWordAndArguments); + lexer->addSkipWord("__glibcpp_class4_requires", SkipWordAndArguments); + lexer->addSkipWord("__glibcpp_function_requires", SkipWordAndArguments); + lexer->addSkipWord("restrict"); + + lexer->addSkipWord("__BEGIN_NAMESPACE_STD"); + lexer->addSkipWord("__END_NAMESPACE_STD"); + lexer->addSkipWord("__BEGIN_NAMESPACE_C99"); + lexer->addSkipWord("__END_NAMESPACE_C99"); + lexer->addSkipWord("__USING_NAMESPACE_STD", SkipWordAndArguments); + + // kde + lexer->addSkipWord("K_SYCOCATYPE", SkipWordAndArguments); + lexer->addSkipWord("EXPORT_DOCKCLASS"); + lexer->addSkipWord("K_EXPORT_COMPONENT_FACTORY", SkipWordAndArguments); + lexer->addSkipWord("K_SYCOCAFACTORY", SkipWordAndArguments); + lexer->addSkipWord("KDE_DEPRECATED"); + + // qt + lexer->addSkipWord("Q_OBJECT"); + lexer->addSkipWord("Q_OVERRIDE", SkipWordAndArguments); + lexer->addSkipWord("Q_ENUMS", SkipWordAndArguments); + lexer->addSkipWord("Q_PROPERTY", SkipWordAndArguments); + lexer->addSkipWord("Q_CLASSINFO", SkipWordAndArguments); + lexer->addSkipWord("Q_SETS", SkipWordAndArguments); + lexer->addSkipWord("Q_UNUSED", SkipWordAndArguments); + lexer->addSkipWord("Q_CREATE_INSTANCE", SkipWordAndArguments); + lexer->addSkipWord("Q_DUMMY_COMPARISON_OPERATOR", SkipWordAndArguments); + lexer->addSkipWord("ACTIVATE_SIGNAL_WITH_PARAM", SkipWordAndArguments); + lexer->addSkipWord("Q_INLINE_TEMPLATES"); + lexer->addSkipWord("Q_TEMPLATE_EXTERN"); + lexer->addSkipWord("Q_TYPENAME"); + lexer->addSkipWord("Q_REFCOUNT"); + lexer->addSkipWord("Q_EXPLICIT"); + lexer->addSkipWord("QMAC_PASCAL"); + lexer->addSkipWord("QT_STATIC_CONST"); + lexer->addSkipWord("QT_STATIC_CONST_IMPL"); + lexer->addSkipWord("QT_WIN_PAINTER_MEMBERS"); + lexer->addSkipWord("QT_NC_MSGBOX"); + lexer->addSkipWord("Q_VARIANT_AS", SkipWordAndArguments); + lexer->addSkipWord("CALLBACK_CALL_TYPE"); + + // qt4 [erbsland] + lexer->addSkipWord("Q_DECLARE_FLAGS", SkipWordAndArguments); + lexer->addSkipWord("Q_DECLARE_OPERATORS_FOR_FLAGS", SkipWordAndArguments); + + // flex + lexer->addSkipWord("yyconst"); + lexer->addSkipWord("YY_RULE_SETUP"); + lexer->addSkipWord("YY_BREAK"); + lexer->addSkipWord("YY_RESTORE_YY_MORE_OFFSET"); + + // gtk + lexer->addSkipWord("G_BEGIN_DECLS"); + lexer->addSkipWord("G_END_DECLS"); + lexer->addSkipWord("G_GNUC_CONST"); + lexer->addSkipWord("G_CONST_RETURN"); + lexer->addSkipWord("GTKMAIN_C_VAR"); + lexer->addSkipWord("GTKVAR"); + lexer->addSkipWord("GDKVAR"); + lexer->addSkipWord("G_GNUC_PRINTF", SkipWordAndArguments); + + // windows + lexer->addSkipWord("WINAPI"); + lexer->addSkipWord("__stdcall"); + lexer->addSkipWord("__cdecl"); + lexer->addSkipWord("_cdecl"); + lexer->addSkipWord("CALLBACK"); + + // gcc extensions + if (!hasMacro("__asm__")) addMacro(Macro("__asm__", "asm")); + if (!hasMacro("__inline")) addMacro(Macro("__inline", "inline")); + if (!hasMacro("__inline__")) addMacro(Macro("__inline__", "inline")); + if (!hasMacro("__const")) addMacro(Macro("__const", "const")); + if (!hasMacro("__const__")) addMacro(Macro("__const__", "const")); + if (!hasMacro("__volatile__")) addMacro(Macro("__volatile__", "volatile")); + if (!hasMacro("__complex__")) addMacro(Macro("__complex__", "")); +} + +void Driver::setupParser(Parser * parser) +{ + Q_UNUSED(parser); +} + +void Driver::clearIncludePaths() +{ + m_includePaths.clear(); +} + +void Driver::addIncludePath(const QString &path) +{ + if (!path.trimmed().isEmpty()) + m_includePaths << path; +} + +QString Driver::findIncludeFile(const Dependence& dep, const QString& fromFile) +{ + QString fileName = dep.first; + + if (dep.second == Dep_Local) { + QString path = QFileInfo(fromFile).absolutePath(); + QFileInfo fileInfo(QFileInfo(path, fileName)); + if (fileInfo.exists() && fileInfo.isFile()) + return fileInfo.absoluteFilePath(); + } + + QStringList includePaths = getCustomIncludePath(fromFile); + + for (QStringList::ConstIterator it = includePaths.constBegin(); it != includePaths.constEnd(); ++it) { + QFileInfo fileInfo(*it, fileName); + if (fileInfo.exists() && fileInfo.isFile()) + return fileInfo.absoluteFilePath(); + } + + return QString(); +} + +QString Driver::findIncludeFile(const Dependence& dep) const +{ + QString fileName = dep.first; + + if (dep.second == Dep_Local) { + QString path = QFileInfo(currentFileName()).absolutePath(); + QFileInfo fileInfo(QFileInfo(path, fileName)); + if (fileInfo.exists() && fileInfo.isFile()) + return fileInfo.absoluteFilePath(); + } + + for (QStringList::ConstIterator it = m_includePaths.begin(); it != m_includePaths.end(); ++it) { + QFileInfo fileInfo(*it, fileName); + if (fileInfo.exists() && fileInfo.isFile()) + return fileInfo.absoluteFilePath(); + } + + return QString(); +} + +void Driver::setResolveDependencesEnabled(bool enabled) +{ + depresolv = enabled; + if (depresolv) + setupPreProcessor(); +} + +bool Driver::shouldParseIncludedFile(const ParsedFilePointer& /*file*/) +{ + return false; +} + +void Driver::setupPreProcessor() {} + +void Driver::fileParsed(ParsedFile & fileName) +{ + Q_UNUSED(fileName); +} + +void Driver::usingMacro(const Macro& macro) +{ + if (m_currentParsedFile) + m_currentParsedFile->usedMacros().addMacro(macro); +#ifdef CACHELEXER + if (m_currentLexerCache) + m_currentLexerCache->addUsedMacro(macro); +#endif +} + +// void Macro::computeHash() const { +// m_idHash = 7 * (HashedString::hashString(m_name) + m_argumentList.count() * 13); +// int a = 1; +// m_idHash += 31 * m_argumentList.count(); +// +// m_valueHash = 27 * (HashedString::hashString(m_body) + (m_isUndefMacro ? 1 : 0)); +// +// for(QList::const_iterator it = m_argumentList.begin(); it != m_argumentList.end(); ++it) { +// a *= 19; +// m_valueHash += a * HashedString::hashString(*it); +// } +// m_valueHashValid = true; +// m_idHashValid = true; +// } + +// MacroSet::MacroSet() : m_idHashValid(false), m_valueHashValid(false) { +// } + +void MacroSet::addMacro(const Macro& macro) +{ + std::pair r = m_usedMacros.insert(macro); + if (!r.second) { + //Make sure the macro added later will be used + m_usedMacros.erase(r.first); + m_usedMacros.insert(macro); + } + + m_idHashValid = m_valueHashValid = false; +} + +void MacroSet::merge(const MacroSet& macros) +{ + Macros m = macros.m_usedMacros; //Swap is needed so the merged macros take precedence + m.insert(m_usedMacros.begin(), m_usedMacros.end()); + m_usedMacros = m; + m_idHashValid = m_valueHashValid = false; +} + + +size_t MacroSet::idHash() const +{ + if (!m_idHashValid) computeHash(); + return m_idHash; +} + +size_t MacroSet::valueHash() const +{ + if (!m_valueHashValid) computeHash(); + return m_valueHash; +} + +void MacroSet::computeHash() const +{ + m_idHash = 0; + m_valueHash = 0; + int mult = 1; + for (Macros::const_iterator it = m_usedMacros.begin(); it != m_usedMacros.end(); ++it) { + mult *= 31; + m_idHash += (*it).idHash(); + m_valueHash += (*it).valueHash(); + } +} + +// void MacroSet::read(QDataStream& stream) { +// stream >> m_idHashValid >> m_idHash >> m_valueHashValid >> m_valueHash; +// int cnt; +// stream >> cnt; +// m_usedMacros.clear(); +// Macro m; +// for(int a = 0; a < cnt; a++) { +// m.read(stream); +// m_usedMacros.insert(m); +// } +// } +// +// void MacroSet::write(QDataStream& stream) const { +// stream << m_idHashValid << m_idHash << m_valueHashValid << m_valueHash; +// stream << m_usedMacros.size(); +// for(Macros::const_iterator it = m_usedMacros.begin(); it != m_usedMacros.end(); ++it) { +// (*it).write(stream); +// } +// } + +/** + * @return All Macros that were used while processing this translation-unit + * */ +MacroSet& ParsedFile::usedMacros() +{ + return m_usedMacros; +} + +const MacroSet& ParsedFile::usedMacros() const +{ + return m_usedMacros; +} + +ParsedFile::ParsedFile(const QString& fileName, const QDateTime& timeStamp) : m_translationUnit(0), m_fileName(fileName), m_timeStamp(timeStamp) +{ + m_includeFiles.insert(fileName); +} + +ParsedFile::ParsedFile(const QByteArray& array) +{ + QByteArray a(array); + QBuffer b(&a); + QDataStream d(&b); + read(d); +} + +QString ParsedFile::includedFrom() const +{ + return m_includedFrom; +} + +void ParsedFile::setIncludedFrom(const QString& str) +{ + m_includedFrom = str; +} + +QByteArray ParsedFile::serialize() const +{ + QByteArray array; + QBuffer b(&array); + QDataStream d(&b); + write(d); + return array; +} + +// void ParsedFile::read(QDataStream& stream) { +// int directIncludeFilesCount; +// stream >> directIncludeFilesCount; +// m_directIncludeFiles.clear(); +// for(int a = 0; a < directIncludeFilesCount; a++) { +// IncludeDesc i; +// stream >> i.local; +// stream >> i.includePath; +// //"parsed" will not be reconstructed +// m_directIncludeFiles.push_back(i); +// } +// stream >> m_fileName; +// stream >> m_timeStamp; +// m_usedMacros.read(stream); +// m_translationUnit = 0; +// m_includeFiles.read(stream); +// } +// +// void ParsedFile::write(QDataStream& stream) const { +// for(QList::const_iterator it = m_directIncludeFiles.begin(); it != m_directIncludeFiles.end(); ++it) { +// stream << (*it).local; +// stream << (*it).includePath; +// } +// stream << m_fileName; +// stream << m_timeStamp; +// m_usedMacros.write(stream); +// m_includeFiles.write(stream); +// } + +void ParsedFile::setTranslationUnit(const TranslationUnitAST::Node& trans) +{ + m_translationUnit = trans; +} + +// HashedStringSet& ParsedFile::includeFiles() { +// return m_includeFiles; +// } + +int ParsedFile::skippedLines() const +{ + return m_skippedLines; +} + +void ParsedFile::setSkippedLines(int lines) +{ + m_skippedLines = lines; +} + +const HashedStringSet& ParsedFile::includeFiles() const +{ + return m_includeFiles; +} + +QString ParsedFile::fileName() const +{ + return m_fileName; +} + +QDateTime ParsedFile::timeStamp() const +{ + return m_timeStamp; +} + +void ParsedFile::addIncludeFiles(const HashedStringSet& includeFiles) +{ + m_includeFiles += includeFiles; +} + +void ParsedFile::addIncludeFile(const QString& includePath, const ParsedFilePointer& parsed, bool localInclude) +{ + m_includeFiles.insert(includePath); + if (parsed) + m_includeFiles += parsed->includeFiles(); + IncludeDesc d; + d.local = localInclude; + d.includePath = includePath; + d.parsed = parsed; + m_directIncludeFiles << d; +} + +const QList& ParsedFile::directIncludeFiles() const +{ + return m_directIncludeFiles; +} + +bool MacroSet::hasMacro(const QString& name) const +{ + Macros::const_iterator it = m_usedMacros.find(Macro(name, "")); + if (it != m_usedMacros.end()) { + return true; + } else { + return false; + } +} + +bool MacroSet::hasMacro(const HashedString& name) const +{ + Macros::const_iterator it = m_usedMacros.find(Macro(name.str(), "")); + if (it != m_usedMacros.end()) { + return true; + } else { + return false; + } +} + +Macro MacroSet::macro(const QString& name) const +{ + Macros::const_iterator it = m_usedMacros.find(Macro(name, "")); + + if (it != m_usedMacros.end()) { + return *it; + } else { + return Macro(); + } +} + +LexerCache* Driver::lexerCache() +{ + return &m_lexerCache; +} + diff -Nru umbrello-4.12.3/lib/cppparser/driver.h umbrello-4.12.90/lib/cppparser/driver.h --- umbrello-4.12.3/lib/cppparser/driver.h 1970-01-01 00:00:00.000000000 +0000 +++ umbrello-4.12.90/lib/cppparser/driver.h 2014-03-05 15:04:09.000000000 +0000 @@ -0,0 +1,474 @@ +/* This file is part of KDevelop + Copyright (C) 2002, 2003 Roberto Raggi + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef DRIVER_H +#define DRIVER_H + +#include "ast.h" + +#include "macro.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "lexercache.h" + + +class Lexer; +class Parser; + +enum { + Dep_Global, + Dep_Local +}; + +typedef QPair Dependence; + +class ParsedFile; +typedef KSharedPtr ParsedFilePointer; + +class ParsedFile: public AbstractParseResult +{ +public: + struct IncludeDesc { + bool local; //Whether it is a local include(#include "local.h", not #include ) + QString includePath; + ParsedFilePointer parsed; //May be zero! + }; +// ParsedFile() { +// } + ParsedFile(QDataStream& s) + { + read(s); + } + + ParsedFile(const QString& fileName, const QDateTime& timeStamp); + + ///Deserializes the ParsedFile from a previous call to serialize(). AST will always be zero after a call to this. + ParsedFile(const QByteArray& array); + + virtual ~ParsedFile() {} + + /** + * @return All Macros that were used while processing this translation-unit. May be modified. + */ + MacroSet& usedMacros(); + const MacroSet& usedMacros() const; + + /** + * @return the count of lines that were skipped while preprocessing the file + * */ + int skippedLines() const; + + void setSkippedLines(int lines); + /** + * @return Absolutely all files included by this one(no matter through how many other files they were included) + */ +// HashedStringSet& includeFiles(); + + const HashedStringSet& includeFiles() const; + + void addIncludeFiles(const HashedStringSet& includeFiles); + + void addIncludeFile(const QString& includePath, const ParsedFilePointer& parsed, bool localInclude); + + ///If this file was parsed while resolving the dependencies of another file, this returns the file this one was included from. Else returns an empty string. + QString includedFrom() const; + + void setIncludedFrom(const QString& str); + /** + * @return Reference to the internal list of all directly included files(without those included indirectly) + */ + const QList& directIncludeFiles() const; + + operator TranslationUnitAST* () const // May be zero + { + if (!this) return 0; + return (TranslationUnitAST*)m_translationUnit.data(); + } + + TranslationUnitAST* operator -> () const + { + if (!this) return 0; + return (TranslationUnitAST*)m_translationUnit.data(); + } + + void setTranslationUnit(const TranslationUnitAST::Node& trans); + + QString fileName() const; + + QDateTime timeStamp() const; + + ///Serializes the content of this class into a byte-array. Note that this does not serialize the AST. + QByteArray serialize() const; + + /*void read(QDataStream& stream); + void write(QDataStream& stream) const;*/ + + virtual void read(QDataStream& stream) + { + int directIncludeFilesCount; + stream >> directIncludeFilesCount; + m_directIncludeFiles.clear(); + for (int a = 0; a < directIncludeFilesCount; a++) { + IncludeDesc i; + Q_INT8 in; + stream >> in; + i.local = in; + stream >> i.includePath; + //"parsed" will not be reconstructed + m_directIncludeFiles.push_back(i); + } + stream >> m_skippedLines; + stream >> m_fileName; + stream >> m_timeStamp; + stream >> m_includedFrom; + m_usedMacros.read(stream); + m_translationUnit = 0; + m_includeFiles.read(stream); + } + + virtual void write(QDataStream& stream) const + { + int i = m_directIncludeFiles.size(); + stream << i; + for (QList::const_iterator it = m_directIncludeFiles.begin(); it != m_directIncludeFiles.end(); ++it) { + Q_INT8 i = (*it).local; + stream << i; + stream << (*it).includePath; + } + stream << m_skippedLines; + stream << m_fileName; + stream << m_timeStamp; + stream << m_includedFrom; + m_usedMacros.write(stream); + m_includeFiles.write(stream); + } + + virtual ParsedFileType type() const + { + return CppParsedFile; + } + +private: + QList m_directIncludeFiles; + MacroSet m_usedMacros; + TranslationUnitAST::Node m_translationUnit; + HashedStringSet m_includeFiles; + int m_skippedLines; + QString m_fileName; + QDateTime m_timeStamp; + QString m_includedFrom; +}; + +/** + * An interface that provides source code to the Driver + */ +class SourceProvider +{ +public: + SourceProvider() {} + virtual ~SourceProvider() {} + + /** + * Get the contents of a file + * \param fileName The name of the file to get the contents for. An absolute + * path should be used. + * \return A QString that contains the contents of the file + */ + virtual QString contents(const QString& fileName) = 0; + + /** + * Check to see if a file has been modified + * \param fileName The name of hte file to get the modification state of. An + * absolute path should be used. + * \return true if the file has been modified + * \return false if the file has not been modified + */ + virtual bool isModified(const QString& fileName) = 0; + +private: + SourceProvider(const SourceProvider& source); + void operator = (const SourceProvider& source); +}; + +class Driver +{ +public: + Driver(); + virtual ~Driver(); + + typedef std::multimap< HashedString, Macro > MacroMap; + + /** + * Get the source provider for this driver. This would be useful for + * getting the text the driver is working with. + */ + SourceProvider* sourceProvider(); + /** + * Sets the source provider the driver will use + * @param sourceProvider the SourceProvider the driver will use + */ + void setSourceProvider(SourceProvider* sourceProvider); + + /** + * @brief Resets the driver + * + * Clears the driver of all problems, dependencies, macros, and include paths and + * removes any translation units that have been parsed + */ + virtual void reset(); + + /** + * Tells the driver to start parsing a file + * @param fileName The name of the file to parse + * @param onlyPreProcesss Tells the driver to only run the file through the preprocessor. Defaults to false + * @param force Force the parsing of the file. Defaults to false + * @param macrosGlobal Should the macros be global? (Global macros are not deleted once a new translation-unit is parsed) + * @return true on success + */ + virtual bool parseFile(const QString& fileName, bool onlyPreProcesss = false, bool force = false, bool macrosGlobal = false); + + /** + * Indicates that the file has been parsed + * @param fileName The name of the file parsed. It is legal to create a ParsedFilePointer on the given item. + */ + virtual void fileParsed(ParsedFile& fileName); + + /** + * Removes the file specified by @p fileName from the driver + * @param fileName The name of the file to remove + */ + virtual void remove + (const QString& fileName); + + /** + * Add a dependency on another header file for @p fileName + * @param fileName The file name to add the dependency for + * @param dep The dependency to add + */ + virtual void addDependence(const QString& fileName, const Dependence& dep); + + /** + * Add a macro to the driver + * @param macro The macro to add to the driver + */ + virtual void addMacro(const Macro& macro); + + /** + * Add a problem to the driver + * @param fileName The file name to add the problem for + * @param problem The problem to add + */ + virtual void addProblem(const QString& fileName, const Problem& problem); + + /** + * The current file name the driver is working with + */ + QString currentFileName() const + { + return m_currentFileName; + } + ParsedFilePointer takeTranslationUnit(const QString& fileName); + + void takeTranslationUnit(const ParsedFile& file); + /** + * Get the translation unit contained in the driver for @p fileName. + * @param fileName The name of the file to get the translation unit for + * @return The TranslationUnitAST pointer that represents the translation unit + * @return 0 if no translation unit exists for the file + */ + ParsedFilePointer translationUnit(const QString& fileName) const; + /** + * Get the dependencies for a file + * @param fileName The file name to get dependencies for + * @return The dependencies for the file + */ + QMap dependences(const QString& fileName) const; + /** + * Get all the macros the driver contains + * @return The macros + */ + const MacroMap& macros() const; + + /** + * Take all macros from the given map(forgetting own macros) */ + void insertMacros(const MacroSet& macros); + /** + * Get the list of problem areas the driver contains + * @param fileName The filename to get problems for + * @return The list of problems for @p fileName + */ + QList problems(const QString& fileName) const; + + void usingString(const HashedString& str); + /** + * Check if we have a macro in the driver + * If the last stacked macro of that name is an undef-macro, false is returned. + * @param name The name of the macro to check for + * @return true if we have the macro in the driver + * @return false if we don't have the macro in the driver + */ + bool hasMacro(const HashedString& name) ; + /** + * Get the macro identified by @p name + * @param name The name of the macro to get + * @return A const reference of the macro object represented by @p name + */ + const Macro& macro(const HashedString& name) const; + /** + * Get the last inserted macro identified by @p name + * @override + * @param name The name of the macro to get + * @return A non-const reference of the macro object represented by @p name + * + */ + Macro& macro(const HashedString& name); + + /** + * Remove the last inserted Macro of that name + * @param macroName The name of the macro to remove + */ + virtual void removeMacro(const HashedString& macroName); + + /** + * Remove all macros from the driver for a certain file + * @param fileName The file name + */ + virtual void removeAllMacrosInFile(const QString& fileName); ///Check when this is called. It may be wrong. + + QStringList includePaths() const + { + return m_includePaths; + } + + virtual QStringList getCustomIncludePath(const QString&); + + + virtual void addIncludePath(const QString &path); + + virtual void clearIncludePaths(); + + /// @todo remove + const QMap &parsedUnits() const + { + return m_parsedUnits; + } + + /** + * Set whether or not to enable dependency resolving for files added to the driver + */ + virtual void setResolveDependencesEnabled(bool enabled); + /** + * Check if dependency resolving is enabled + * \return true if dependency resolving is enabled + * \return false if dependency resolving is disabled + */ + bool isResolveDependencesEnabled() const + { + return depresolv; + } + + void setMaxDependenceDepth(int depth); + + /** + * Used by the Lexer to indicate that a Macro was used + * @param macro The used macro + * */ + void usingMacro(const Macro& macro); + + /** + * Returns the local instance of the lexer-cache, can be used from outside to control the cache-behavior. + * */ + LexerCache* lexerCache(); + + ///This uses getCustomIncludePath(..) to resolve the include-path internally + QString findIncludeFile(const Dependence& dep, const QString& fromFile); + +protected: + ///This uses the state of the parser to find the include-file + QString findIncludeFile(const Dependence& dep) const; + + /** + * Set up the lexer. + */ + virtual void setupLexer(Lexer* lexer); + /** + * Setup the parser + */ + virtual void setupParser(Parser* parser); + /** + * Set up the preprocessor + */ + virtual void setupPreProcessor(); + + /** + * Is code-information for this file already available? If false is returned, the file will be parsed. + * Code-model and static repository should be checked to find out whether the file is already available. + * This function is only used when dependency-resolving is activated. + * @arg file absolute path to the file + */ + virtual bool shouldParseIncludedFile(const ParsedFilePointer& /*file*/); + + void clearMacros(); + + void clearParsedMacros(); + +private: + QMap& findOrInsertDependenceList(const QString& fileName); + QList& findOrInsertProblemList(const QString& fileName); + + +private: + QString m_currentFileName; + QString m_currentMasterFileName; + typedef QMap DependenceMap; + typedef QMap< QString, DependenceMap> DependencesMap; + DependencesMap m_dependences; + MacroMap m_macros; + QMap< QString, QList > m_problems; + QMap m_parsedUnits; + QStringList m_includePaths; +uint depresolv : + 1; + Lexer *lexer; + SourceProvider* m_sourceProvider; + + ParsedFilePointer m_currentParsedFile; + CachedLexedFilePointer m_currentLexerCache; + LexerCache m_lexerCache; + + int m_dependenceDepth; + int m_maxDependenceDepth; + + class ParseHelper; + friend class ParseHelper; + +private: + Driver(const Driver& source); + void operator = (const Driver& source); +}; + +#endif diff -Nru umbrello-4.12.3/lib/cppparser/errors.cpp umbrello-4.12.90/lib/cppparser/errors.cpp --- umbrello-4.12.3/lib/cppparser/errors.cpp 1970-01-01 00:00:00.000000000 +0000 +++ umbrello-4.12.90/lib/cppparser/errors.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -0,0 +1,25 @@ +/* This file is part of KDevelop + Copyright (C) 2002, 2003 Roberto Raggi + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include "errors.h" +#include + +QT_STATIC_CONST_IMPL Error& Errors::InternalError = Error(1, -1, i18n("Internal Error")); +QT_STATIC_CONST_IMPL Error& Errors::SyntaxError = Error(2, -1, i18n("Syntax Error before '%1'")); +QT_STATIC_CONST_IMPL Error& Errors::ParseError = Error(3, -1, i18n("Parse Error before '%1'")); diff -Nru umbrello-4.12.3/lib/cppparser/errors.h umbrello-4.12.90/lib/cppparser/errors.h --- umbrello-4.12.3/lib/cppparser/errors.h 1970-01-01 00:00:00.000000000 +0000 +++ umbrello-4.12.90/lib/cppparser/errors.h 2014-03-05 15:04:09.000000000 +0000 @@ -0,0 +1,46 @@ +/* This file is part of KDevelop + Copyright (C) 2002, 2003 Roberto Raggi + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef ERRORS_H +#define ERRORS_H + +#include + + +struct Error { + int code; + int level; + QString text; + + Error(int c, int l, const QString& s) + : code(c), level(l), text(s) + {} +}; + +class Errors +{ +public: + QT_STATIC_CONST Error& InternalError; + QT_STATIC_CONST Error& SyntaxError; + QT_STATIC_CONST Error& ParseError; +}; + + + +#endif diff -Nru umbrello-4.12.3/lib/cppparser/keywords.h umbrello-4.12.90/lib/cppparser/keywords.h --- umbrello-4.12.3/lib/cppparser/keywords.h 1970-01-01 00:00:00.000000000 +0000 +++ umbrello-4.12.90/lib/cppparser/keywords.h 2014-03-05 15:04:09.000000000 +0000 @@ -0,0 +1,96 @@ +// +// Keywords file is included in lookup.cpp +// [erbsland] replacement for old hash table +// +#define INSERT(x, y) keywords.insert(std::pair(x, y)) +// KDE Keywords +INSERT("K_DCOP", Token_K_DCOP); +INSERT("k_dcop", Token_k_dcop); +INSERT("k_dcop_signals", Token_k_dcop_signals); + +// Qt Keywords +INSERT("Q_OBJECT", Token_Q_OBJECT); +INSERT("signals", Token_signals); +INSERT("Q_SLOTS", Token_slots); +INSERT("slots", Token_slots); +INSERT("emit", Token_emit); +INSERT("foreach", Token_foreach); + +// C++ Keywords +INSERT("__int64", Token_int); +INSERT("__asm__", Token_asm); +INSERT("and", Token_and); +INSERT("and_eq", Token_and_eq); +INSERT("asm", Token_asm); +INSERT("auto", Token_auto); +INSERT("bitand", Token_bitand); +INSERT("bitor", Token_bitor); +INSERT("bool", Token_bool); +INSERT("break", Token_break); +INSERT("case", Token_case); +INSERT("catch", Token_catch); +INSERT("char", Token_char); +INSERT("class", Token_class); +INSERT("compl", Token_compl); +INSERT("const", Token_const); +INSERT("const_cast", Token_const_cast); +INSERT("continue", Token_continue); +INSERT("default", Token_default); +INSERT("delete", Token_delete); +INSERT("do", Token_do); +INSERT("double", Token_double); +INSERT("dynamic_cast", Token_dynamic_cast); +INSERT("else", Token_else); +INSERT("enum", Token_enum); +INSERT("explicit", Token_explicit); +INSERT("export", Token_export); +INSERT("extern", Token_extern); +INSERT("float", Token_float); +INSERT("for", Token_for); +INSERT("friend", Token_friend); +INSERT("goto", Token_goto); +INSERT("if", Token_if); +INSERT("inline", Token_inline); +INSERT("int", Token_int); +INSERT("long", Token_long); +INSERT("mutable", Token_mutable); +INSERT("namespace", Token_namespace); +INSERT("new", Token_new); +INSERT("not", Token_not); +INSERT("not_eq", Token_not_eq); +INSERT("operator", Token_operator); +INSERT("or", Token_or); +INSERT("or_eq", Token_or_eq); +INSERT("private", Token_private); +INSERT("protected", Token_protected); +INSERT("public", Token_public); +INSERT("register", Token_register); +INSERT("reinterpret_cast", Token_reinterpret_cast); +INSERT("return", Token_return); +INSERT("short", Token_short); +INSERT("signed", Token_signed); +INSERT("sizeof", Token_sizeof); +INSERT("static", Token_static); +INSERT("static_cast", Token_static_cast); +INSERT("struct", Token_struct); +INSERT("switch", Token_switch); +INSERT("template", Token_template); +INSERT("this", Token_this); +INSERT("throw", Token_throw); +INSERT("try", Token_try); +INSERT("typedef", Token_typedef); +INSERT("typeid", Token_typeid); +INSERT("typename", Token_typename); +INSERT("union", Token_union); +INSERT("unsigned", Token_unsigned); +INSERT("using", Token_using); +INSERT("virtual", Token_virtual); +INSERT("void", Token_void); +INSERT("volatile", Token_volatile); +INSERT("while", Token_while); +INSERT("xor", Token_xor); +INSERT("xor_eq", Token_xor_eq); + +// +// End of file +// diff -Nru umbrello-4.12.3/lib/cppparser/lexercache.cpp umbrello-4.12.90/lib/cppparser/lexercache.cpp --- umbrello-4.12.3/lib/cppparser/lexercache.cpp 1970-01-01 00:00:00.000000000 +0000 +++ umbrello-4.12.90/lib/cppparser/lexercache.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -0,0 +1,266 @@ +/*************************************************************************** + copyright : (C) 2006 by David Nolden + email : david.nolden.kdevelop@art-master.de +***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "lexercache.h" +#include "driver.h" +#include + +LexerCache::LexerCache(Driver* d) : m_driver(d) {} + +void LexerCache::addLexedFile(const CachedLexedFilePointer& file) +{ + //kdDebug(9007) << "LexerCache: adding an instance of " << file->fileName().str() << endl; + + std::pair< CachedLexedFileMap::iterator, CachedLexedFileMap::iterator> files = m_files.equal_range(file->fileName()); + + if (files.first == files.second) { + m_files.insert(std::make_pair(file->fileName(), file)); + } else { + //Make sure newer files appear first + m_files.insert(files.first, std::make_pair(file->fileName(), file)); + } + + int cnt = 0; + while (files.first != files.second) { + if (sourceChanged(*(*(files.first)).second)) { + m_files.erase(files.first++); + } else { + cnt++; + files.first++; + } + } + //kdDebug(9007) << "LexerCache: new count of cached instances for the file: " << cnt << endl; +} + +CachedLexedFilePointer LexerCache::lexedFile(const HashedString& fileName) +{ + initFileModificationCache(); + std::pair< CachedLexedFileMap::iterator, CachedLexedFileMap::iterator> files = m_files.equal_range(fileName); + + ///@todo optimize with standard-algorithms(by first computing the intersection) + + /* if(files.first != files.second) + //kdDebug(9007) << "LexerCache: cache for file " << fileName.str() << " is not empty" << endl; + else + //kdDebug(9007) << "LexerCache: cache for file " << fileName.str() << " is empty" << endl;*/ + + while (files.first != files.second) { + const CachedLexedFile& file(*(*(files.first)).second); + if (sourceChanged(file)) { + //kdDebug(9007) << "LexerCache: cache for file " << fileName.str() << " is being discarded because the file was modified" << endl; + m_files.erase(files.first++); + continue; + } + bool success = true; + //Make sure that none of the macros stored in the driver affect the file in a different way than the one before + Driver::MacroMap::const_iterator end = m_driver->macros().end(); + for (Driver::MacroMap::const_iterator rit = m_driver->macros().begin(); rit != end;) { + Driver::MacroMap::const_iterator it = rit; + ++rit; + if (rit != end && (*it).first == (*rit).first) continue; //Always only use the last macro of the same name for comparison, it is on top of the macro-stack + if ((*it).second.isUndef()) continue; //Undef-macros theoretically don't exist + + if (file.hasString((*it).first)) { + if (file.m_usedMacros.hasMacro((*it).first)) { + Macro m(file.m_usedMacros.macro((*it).first.str())); + if (!(m == (*it).second)) { + //kdDebug(9007) << "LexerCache: The cached file " << fileName.str() << " depends on the string \"" << (*it).first.str() << "\" and used a macro for it with the body \"" << m.body() << "\"(from " << m.fileName() << "), but the driver contains the same macro with body \"" << (*it).second.body() << "\"(from " << (*it).second.fileName() << "), cache is not used" << endl; + + //Macro with the same name was used, but it is different + success = false; + break; + } + + } else { + //There is a macro that affects the file, but was not used while the previous parse + //kdDebug(9007) << "LexerCache: The cached file " << fileName.str() << " depends on the string \"" << (*it).first.str() << "\" and the driver contains a macro of that name with body \"" << (*it).second.body() << "\"(from " << (*it).second.fileName() << "), the cached file is not used" << endl; + success = false; + break; + } + } + } + //Make sure that all external macros used by the file now exist too + MacroSet::Macros::const_iterator end2 = file.usedMacros().macros().end(); + for (MacroSet::Macros::const_iterator it = file.usedMacros().macros().begin(); it != end2; ++it) { + if (!m_driver->hasMacro(HashedString((*it).name()))) { + //kdDebug(9007) << "LexerCache: The cached file " << fileName.str() << " used a macro called \"" << it->name() << "\"(from " << it->fileName() << "), but the driver does not contain that macro, the cached file is not used" << endl; + success = false; + break; + } + } + + if (success) { + //kdDebug(9007) << "LexerCache: Using cached file " << fileName.str() << endl; + (*files.first).second->access(); + return (*files.first).second; + } + ++files.first; + } + return CachedLexedFilePointer(); +} + +QDateTime LexerCache::fileModificationTimeCached(const HashedString& fileName) +{ + FileModificationMap::const_iterator it = m_fileModificationCache.find(fileName); + if (it != m_fileModificationCache.end()) { + ///Use the cache for 10 seconds + if ((*it).second.m_readTime.secsTo(m_currentDateTime) < 10) { + return (*it).second.m_modificationTime; + } + } + + QFileInfo fileInfo(fileName.str()); + m_fileModificationCache[fileName].m_readTime = QDateTime::currentDateTime(); + m_fileModificationCache[fileName].m_modificationTime = fileInfo.lastModified(); + return fileInfo.lastModified(); + +} + +//Should be cached too! +bool LexerCache::sourceChanged(const CachedLexedFile& file) +{ + //@todo Check if any of the dependencies changed + + QDateTime modTime = fileModificationTimeCached(file.fileName()); + + if (modTime != file.modificationTime()) + return true; + + for (QMap::const_iterator it = file.allModificationTimes().begin(); it != file.allModificationTimes().end(); ++it) { + QDateTime modTime = fileModificationTimeCached(it.key()); + if (modTime != *it) + return true; + } + + return false; +} + + +void LexerCache::clear() +{ + m_files.clear(); + m_totalStringSet.clear(); + m_fileModificationCache.clear(); +} + +void LexerCache::erase(const CacheNode* node) +{ + std::pair< CachedLexedFileMap::iterator, CachedLexedFileMap::iterator> files = m_files.equal_range(((const CachedLexedFile*)(node))->fileName()); + while (files.first != files.second) { + if ((*files.first).second == ((const CachedLexedFile*)(node))) { + m_files.erase(files.first); + return; + } + files.first++; + } + //kdDebug(9007) << "Error: could not find a node in the list for file " << ((const CachedLexedFile*)(node))->fileName().str() << endl; +} + +CachedLexedFile::CachedLexedFile(const HashedString& fileName, LexerCache* manager) : CacheNode(manager), m_fileName(fileName) +{ + QFileInfo fileInfo(fileName.str()); + m_modificationTime = fileInfo.lastModified(); + m_allModificationTimes[ fileName ] = m_modificationTime; +} + +void CachedLexedFile::addDefinedMacro(const Macro& macro) +{ +#ifdef LEXERCACHE_DEBUG + //kdDebug(9007) << "defined macro " << macro.name() << endl; +#endif + m_definedMacros.addMacro(macro); + m_definedMacroNames.insert(HashedString(macro.name())); +} + +void CachedLexedFile::addUsedMacro(const Macro& macro) +{ + if (!m_definedMacros.hasMacro(macro.name())) { +#ifdef LEXERCACHE_DEBUG + //kdDebug(9007) << "used macro " << macro.name() << endl; +#endif + m_usedMacros.addMacro(macro); + } +} + +void CachedLexedFile::addIncludeFile(const HashedString& file, const QDateTime& modificationTime) +{ + m_includeFiles.insert(file); + m_allModificationTimes[file] = modificationTime; +} + + +QDateTime CachedLexedFile::modificationTime() const +{ + return m_modificationTime; +} + +void CachedLexedFile::addProblem(const Problem& p) +{ + m_problems << p; +} + +QList CachedLexedFile::problems() const +{ + return m_problems; +} + +//The parameter should be a CachedLexedFile that was lexed AFTER the content of this file +void CachedLexedFile::merge(const CachedLexedFile& file) +{ +#ifdef LEXERCACHE_DEBUG + //kdDebug(9007) << fileName().str() << ": merging " << file.fileName().str() << endl << "defined in this: " << m_definedMacroNames.print().c_str() << endl << "defined macros in other: " << file.m_definedMacroNames.print().c_str() << endl;; +#endif + HashedStringSet tempStrings = file.m_strings; + tempStrings -= m_definedMacroNames; + m_strings += tempStrings; + m_includeFiles += file.m_includeFiles; + //Only add macros to the usedMacros-list that were not defined locally + for (MacroSet::Macros::const_iterator it = file.m_usedMacros.macros().begin(); it != file.m_usedMacros.macros().end(); ++it) { + if (!m_definedMacros.hasMacro((*it).name())) { ///If the macro was not defined locally, add it to the macros-list. +#ifdef LEXERCACHE_DEBUG + //kdDebug(9007) << "inserting used macro " << (*it).name() << endl; +#endif + m_usedMacros.addMacro(*it); + } + } + + m_definedMacros.merge(file.m_definedMacros); + m_definedMacroNames += file.m_definedMacroNames; + + for (QMap::const_iterator it = file.m_allModificationTimes.begin(); it != file.m_allModificationTimes.end(); ++it) + m_allModificationTimes[it.key()] = *it; + + +#ifdef LEXERCACHE_DEBUG + //kdDebug(9007) << fileName().str() << ": defined in this after merge: " << m_definedMacroNames.print().c_str() << endl; +#endif + m_problems += file.m_problems; +} + +size_t CachedLexedFile::hash() const +{ + return m_usedMacros.valueHash() + m_usedMacros.idHash() + m_definedMacros.idHash() + m_definedMacros.valueHash() + m_strings.hash(); +} + +void LexerCache::initFileModificationCache() +{ + m_currentDateTime = QDateTime::currentDateTime(); +} + +void LexerCache::saveMemory() +{ + m_fileModificationCache.clear(); + + m_totalStringSet.clear(); ///it's unclear how often this should be emptied. It may happen that completely unused strings end up in this set, then deleting it will save us memory. +} diff -Nru umbrello-4.12.3/lib/cppparser/lexercache.h umbrello-4.12.90/lib/cppparser/lexercache.h --- umbrello-4.12.3/lib/cppparser/lexercache.h 1970-01-01 00:00:00.000000000 +0000 +++ umbrello-4.12.90/lib/cppparser/lexercache.h 2014-03-05 15:04:09.000000000 +0000 @@ -0,0 +1,174 @@ +/*************************************************************************** + copyright : (C) 2006 by David Nolden + email : david.nolden.kdevelop@art-master.de +***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef LEXERCACHE_H +#define LEXERCACHE_H +#include +#include +#include "macro.h" +#include +#include +#include +#include +#include "cachemanager.h" + +//#define LEXERCACHE_DEBUG + +class LexerCache; + +class CachedLexedFile : public KShared, public CacheNode +{ +public: + ///@todo add and manage the set of included files + CachedLexedFile(const HashedString& fileName, LexerCache* manager); + + inline void addString(const HashedString& string) + { + if (!m_definedMacroNames[ string ]) { + m_strings.insert(string); + } + } + + void addDefinedMacro(const Macro& macro); + + void addUsedMacro(const Macro& macro); + + void addIncludeFile(const HashedString& file, const QDateTime& modificationTime); + + inline bool hasString(const HashedString& string) const + { + return m_strings[string]; + } + + QDateTime modificationTime() const; + + void addProblem(const Problem& p); + + QList problems() const; + + //The parameter should be a CachedLexedFile that was lexed AFTER the content of this file + void merge(const CachedLexedFile& file); + + bool operator < (const CachedLexedFile& rhs) const + { + return m_fileName < rhs.m_fileName; + } + + size_t hash() const; + + HashedString fileName() const + { + return m_fileName; + } + + const HashedStringSet& includeFiles() const + { + return m_includeFiles; + } + + const MacroSet& definedMacros() const + { + return m_definedMacros; + } + + const MacroSet& usedMacros() const + { + return m_usedMacros; + } + + ///Should contain a modification-time for each include-file + const QMap& allModificationTimes() const + { + return m_allModificationTimes; + } + +private: + friend class LexerCache; + HashedString m_fileName; + QDateTime m_modificationTime; + HashedStringSet m_strings; //Set of all strings that can be affected by macros from outside + HashedStringSet m_includeFiles; //Set of all files + MacroSet m_usedMacros; //Set of all macros that were used, and were defined outside of this file + MacroSet m_definedMacros; //Set of all macros that were defined while lexing this file + HashedStringSet m_definedMacroNames; + QList m_problems; + QMap m_allModificationTimes; + /* + Needed data: + 1. Set of all strings that appear in this file(For memory-reasons they should be taken from a global string-repository, because many will be the same) + 2. Set of all macros that were defined outside of, but affected the file + + Algorithm: + Iterate over all available macros, and check whether they affect the file. If it does, make sure that the macro is in the macro-set and has the same body. + If the check fails: We need to reparse. + */ +}; + +typedef KSharedPtr CachedLexedFilePointer; + +struct CachedLexedFilePointerCompare { + bool operator() (const CachedLexedFilePointer& lhs, const CachedLexedFilePointer& rhs) const + { + return (*lhs) < (*rhs); + } +}; + +class Driver; + +class LexerCache : public CacheManager +{ +public: + LexerCache(Driver* d); + virtual ~LexerCache() {} + + void addLexedFile(const CachedLexedFilePointer& file); + + ///Returns zero if no fitting file is available for the current context + CachedLexedFilePointer lexedFile(const HashedString& fileName); + + void clear(); + + const HashedString& unifyString(const HashedString& str) + { + __gnu_cxx::hash_set::const_iterator it = m_totalStringSet.find(str); + if (it != m_totalStringSet.end()) { + return *it; + } else { + m_totalStringSet.insert(str); + return str; + } + } + virtual void saveMemory(); +private: + ///before this can be called, initFileModificationCache should be called once + QDateTime fileModificationTimeCached(const HashedString& fileName); + void initFileModificationCache(); + virtual void erase(const CacheNode* node); + bool sourceChanged(const CachedLexedFile& file);///Returns true if the file itself, or any of its dependencies was modified. + //typedef __gnu_cxx::hash_multimap CachedLexedFileMap; + typedef std::multimap CachedLexedFileMap; + CachedLexedFileMap m_files; + __gnu_cxx::hash_set m_totalStringSet; ///This is used to reduce memory-usage: Most strings appear again and again. Because QString is reference-counted, this set contains a unique copy of each string to used for each appearance of the string + struct FileModificationCache { + QDateTime m_readTime; + QDateTime m_modificationTime; + }; + typedef __gnu_cxx::hash_map FileModificationMap; + FileModificationMap m_fileModificationCache; + Driver* m_driver; + QDateTime m_currentDateTime; +}; + + +#endif diff -Nru umbrello-4.12.3/lib/cppparser/lexer.cpp umbrello-4.12.90/lib/cppparser/lexer.cpp --- umbrello-4.12.3/lib/cppparser/lexer.cpp 1970-01-01 00:00:00.000000000 +0000 +++ umbrello-4.12.90/lib/cppparser/lexer.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -0,0 +1,1035 @@ +/* This file is part of KDevelop + Copyright (C) 2002, 2003 Roberto Raggi + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include "lexer.h" +#include "lookup.h" + +#include +#include + +#include +#include +#include + +DEBUG_REGISTER_DISABLED(Lexer) + +#if defined(KDEVELOP_BGPARSER) +#include + +class KDevTread: public QThread +{ +public: + static void yield() + { + msleep(0); + } +}; + +inline void qthread_yield() +{ + KDevTread::yield(); +} + +#endif + +#define CREATE_TOKEN(type, start, len) Token((type), (start), (len), m_source) +#define ADD_TOKEN(tk) m_tokens.insert(m_size++, new Token(tk)); + +using namespace std; + +struct LexerData { + typedef QMap Scope; + typedef QList StaticChain; + + StaticChain staticChain; + + void beginScope() + { + Scope scope; + staticChain.push_front(scope); + } + + void endScope() + { + staticChain.pop_front(); + } + + void bind(const QString& name, const QString& value) + { + Q_ASSERT(staticChain.size() > 0); + staticChain.front().insert(name, value); + } + + bool hasBind(const QString& name) const + { + StaticChain::ConstIterator it = staticChain.begin(); + while (it != staticChain.end()) { + const Scope& scope = *it; + ++it; + + if (scope.contains(name)) + return true; + } + + return false; + } + + QString apply(const QString& name) const + { + StaticChain::ConstIterator it = staticChain.begin(); + while (it != staticChain.end()) { + const Scope& scope = *it; + ++it; + + if (scope.contains(name)) + return scope[ name ]; + } + + return QString(); + } + +}; + +Lexer::Lexer(Driver* driver) + : d(new LexerData), + m_driver(driver), + m_recordComments(true), + m_recordWhiteSpaces(false), + m_skipWordsEnabled(true), + m_preprocessorEnabled(true), + m_reportWarnings(false), + m_reportMessages(false) +{ + reset(); + d->beginScope(); +} + +Lexer::~Lexer() +{ + d->endScope(); + delete(d); + qDeleteAll(m_tokens); + m_tokens.clear(); +} + +void Lexer::setSource(const QString& source) +{ + reset(); + m_source = source; + m_ptr = offset(0); + m_endPtr = offset(m_source.length()); + m_inPreproc = false; + if (!source.isEmpty()) { + m_currentChar = m_source[0]; + } else { + m_currentChar = QChar(); + } + + tokenize(); +} + +int Lexer::skippedLines() const +{ + return m_skippedLines; +} + +void Lexer::reset() +{ + m_skippedLines = 0; + m_index = 0; + m_size = 0; + m_tokens.clear(); + m_source = QString(); + m_ptr = 0; + m_endPtr = 0; + m_startLine = false; + m_ifLevel = 0; + m_skipping.resize(200); + m_skipping.fill(0); + m_trueTest.resize(200); + m_trueTest.fill(0); + + m_currentLine = 0; + m_currentColumn = 0; +} + +// ### should all be done with a "long" type IMO +int Lexer::toInt(const Token& token) +{ + QString s = token.text(); + if (token.type() == Token_number_literal) { + // hex literal ? + if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) + return s.mid(2).toInt(0, 16); + QString n; + int i = 0; + while (i < int(s.length()) && s[i].isDigit()) + n += s[i++]; + // ### respect more prefixes and suffixes ? + return n.toInt(); + } else if (token.type() == Token_char_literal) { + int i = s[0] == 'L' ? 2 : 1; // wide char ? + if (s[i] == '\\') { + // escaped char + int c = s[i+1].unicode(); + switch (c) { + case '0': + return 0; + case 'n': + return '\n'; + // ### more + default: + return c; + } + } else { + return s[i].unicode(); + } + } else { + return 0; + } +} + +void Lexer::getTokenPosition(const Token& token, int* line, int* col) +{ + token.getStartPosition(line, col); +} + +void Lexer::nextToken(Token& tk, bool stopOnNewline) +{ + int op = 0; + + if (m_size == (int)m_tokens.size()) { + m_tokens.resize(m_tokens.size() + 5000 + 1); + } + + readWhiteSpaces(!stopOnNewline); + + int startLine = m_currentLine; + int startColumn = m_currentColumn; + + QChar ch = currentChar(); + QChar ch1 = peekChar(); + + if (ch.isNull() || ch.isSpace()) { + /* skip */ + } else if (m_startLine && ch == '#') { + + nextChar(); // skip # + readWhiteSpaces(false); // skip white spaces + m_startLine = false; + + int start = currentPosition(); + readIdentifier(); // read the directive + QString directive = m_source.mid(start, currentPosition() - start); + + handleDirective(directive); + } else if (m_startLine && m_skipping[ m_ifLevel ]) { + // skip line and continue + m_startLine = false; + int ppe = preprocessorEnabled(); + setPreprocessorEnabled(false); + while (!currentChar().isNull() && currentChar() != '\n') { + Token tok(m_source); + nextToken(tok, true); + } + ++m_skippedLines; + m_startLine = true; + setPreprocessorEnabled(ppe); + return; + } else if (ch == '/' && ch1 == '/') { + int start = currentPosition(); + readLineComment(); + if (recordComments()) { + tk = CREATE_TOKEN(Token_comment, start, currentPosition() - start); + tk.setStartPosition(startLine, startColumn); + tk.setEndPosition(m_currentLine, m_currentColumn); + } + } else if (ch == '/' && ch1 == '*') { + int start = currentPosition(); + nextChar(2); + readMultiLineComment(); + + if (recordComments()) { + tk = CREATE_TOKEN(Token_comment, start, currentPosition() - start); + tk.setStartPosition(startLine, startColumn); + tk.setEndPosition(m_currentLine, m_currentColumn); + } + } else if (ch == '\'' || (ch == 'L' && ch1 == '\'')) { + int start = currentPosition(); + readCharLiteral(); + tk = CREATE_TOKEN(Token_char_literal, start, currentPosition() - start); + tk.setStartPosition(startLine, startColumn); + tk.setEndPosition(m_currentLine, m_currentColumn); + } else if (ch == '"') { + int start = currentPosition(); + readStringLiteral(); + tk = CREATE_TOKEN(Token_string_literal, start, currentPosition() - start); + tk.setStartPosition(startLine, startColumn); + tk.setEndPosition(m_currentLine, m_currentColumn); + } else if (ch.isLetter() || ch == '_') { + int start = currentPosition(); + readIdentifier(); + HashedString ide = m_source.mid(start, currentPosition() - start); + int k = Lookup::find(ide); + if (k == -1 && m_preprocessorEnabled) m_driver->usingString(ide); + + if (m_preprocessorEnabled && m_driver->hasMacro(ide) && + (k == -1 || !m_driver->macro(ide).body().isEmpty())) { + + + bool preproc = m_preprocessorEnabled; + m_preprocessorEnabled = false; + + d->beginScope(); + + int svLine = currentLine(); + int svColumn = currentColumn(); + + Macro m = m_driver->macro(ide); + m_driver->usingMacro(m); + + QString ellipsisArg; + + if (m.hasArguments()) { + int endIde = currentPosition(); + + readWhiteSpaces(); + if (currentChar() == '(') { + nextChar(); + int argIdx = 0; + int argCount = m.argumentList().size(); + while (!currentChar().isNull() && argIdxbind(argName, arg); + else + ellipsisArg += arg; + + if (currentChar() == ',') { + nextChar(); + if (!ellipsis) { + ++argIdx; + } else { + ellipsisArg += ", "; + } + } else if (currentChar() == ')') { + break; + } + } + if (currentChar() == ')') { + // valid macro + nextChar(); + } + } else { + tk = CREATE_TOKEN(Token_identifier, start, endIde - start); + tk.setStartPosition(svLine, svColumn); + tk.setEndPosition(svLine, svColumn + (endIde - start)); + + m_startLine = false; + + d->endScope(); // OPS!! + m_preprocessorEnabled = preproc; + return; + } + } + + int argsEndAtLine = currentLine(); + int argsEndAtColumn = currentColumn(); + +#if defined(KDEVELOP_BGPARSER) + qthread_yield(); +#endif + insertCurrent(m.body()); + + // tokenize the macro body + + QString textToInsert; + + setEndPtr(offset(currentPosition() + m.body().length())); + + while (!currentChar().isNull()) { + + readWhiteSpaces(); + + Token tok(m_source); + nextToken(tok); + + bool stringify = !m_inPreproc && tok == '#'; + bool merge = !m_inPreproc && tok == Token_concat; + + if (stringify || merge) + nextToken(tok); + + if (tok == Token_eof) + break; + + QString tokText = tok.text(); + HashedString str = (tok == Token_identifier && d->hasBind(tokText)) ? d->apply(tokText) : tokText; + if (str == ide) { + //Problem p(i18n("unsafe use of macro '%1', macro is ignored").arg(ide.str()), m_currentLine, m_currentColumn, Problem::Level_Warning); + //m_driver->addProblem(m_driver->currentFileName(), p); + m_driver->removeMacro(ide); + // str = QString::null; + } + + if (stringify) { + textToInsert.append(QString::fromLatin1("\"") + str.str() + QString::fromLatin1("\" ")); + } else if (merge) { + textToInsert.truncate(textToInsert.length() - 1); + textToInsert.append(str.str() + QString::fromLatin1(" ")); + } else if (tok == Token_ellipsis && d->hasBind("...")) { + textToInsert.append(ellipsisArg); + } else { + textToInsert.append(str.str() + QString::fromLatin1(" ")); + } + } + +#if defined(KDEVELOP_BGPARSER) + qthread_yield(); +#endif + insertCurrent(textToInsert); //also corrects the end-pointer + + d->endScope(); + m_preprocessorEnabled = preproc; + //m_driver->addMacro(m); + m_currentLine = argsEndAtLine; + m_currentColumn = argsEndAtColumn; + } else if (k != -1) { + tk = CREATE_TOKEN(k, start, currentPosition() - start); + tk.setStartPosition(startLine, startColumn); + tk.setEndPosition(m_currentLine, m_currentColumn); + } else if (m_skipWordsEnabled) { + __gnu_cxx::hash_map< HashedString, QPair >::iterator pos = m_words.find(ide); + if (pos != m_words.end()) { + if ((*pos).second.first == SkipWordAndArguments) { + readWhiteSpaces(); + if (currentChar() == '(') + skip('(', ')'); + } + if (!(*pos).second.second.isEmpty()) { +#if defined(KDEVELOP_BGPARSER) + qthread_yield(); +#endif + insertCurrent(QString(" ") + (*pos).second.second + QString(" ")); + } + } else if ( /*qt_rx.exactMatch(ide) ||*/ + ide.str().endsWith(QLatin1String("EXPORT")) || + (ide.str().startsWith(QLatin1String("Q_EXPORT")) && ide.str() != QLatin1String("Q_EXPORT_INTERFACE")) || + ide.str().startsWith(QLatin1String("QM_EXPORT")) || + ide.str().startsWith(QLatin1String("QM_TEMPLATE"))) { + + readWhiteSpaces(); + if (currentChar() == '(') + skip('(', ')'); + } else if (ide.str().startsWith(QLatin1String("K_TYPELIST_")) || ide.str().startsWith(QLatin1String("TYPELIST_"))) { + tk = CREATE_TOKEN(Token_identifier, start, currentPosition() - start); + tk.setStartPosition(startLine, startColumn); + tk.setEndPosition(m_currentLine, m_currentColumn); + readWhiteSpaces(); + if (currentChar() == '(') + skip('(', ')'); + } else { + tk = CREATE_TOKEN(Token_identifier, start, currentPosition() - start); + tk.setStartPosition(startLine, startColumn); + tk.setEndPosition(m_currentLine, m_currentColumn); + } + } else { + tk = CREATE_TOKEN(Token_identifier, start, currentPosition() - start); + tk.setStartPosition(startLine, startColumn); + tk.setEndPosition(m_currentLine, m_currentColumn); + } + } else if (ch.isNumber()) { + int start = currentPosition(); + readNumberLiteral(); + tk = CREATE_TOKEN(Token_number_literal, start, currentPosition() - start); + tk.setStartPosition(startLine, startColumn); + tk.setEndPosition(m_currentLine, m_currentColumn); + } else if (-1 != (op = findOperator3())) { + tk = CREATE_TOKEN(op, currentPosition(), 3); + nextChar(3); + tk.setStartPosition(startLine, startColumn); + tk.setEndPosition(m_currentLine, m_currentColumn); + } else if (-1 != (op = findOperator2())) { + tk = CREATE_TOKEN(op, currentPosition(), 2); + nextChar(2); + tk.setStartPosition(startLine, startColumn); + tk.setEndPosition(m_currentLine, m_currentColumn); + } else { + tk = CREATE_TOKEN(ch.unicode(), currentPosition(), 1); + nextChar(); + tk.setStartPosition(startLine, startColumn); + tk.setEndPosition(m_currentLine, m_currentColumn); + } + + m_startLine = false; +} + + +void Lexer::tokenize() +{ + m_startLine = true; + m_size = 0; + + for (;;) { + Token tk(m_source); + nextToken(tk); + + if (tk.type() != -1) + ADD_TOKEN(tk); + + if (currentChar().isNull()) + break; + } + + Token tk = CREATE_TOKEN(Token_eof, currentPosition(), 0); + tk.setStartPosition(m_currentLine, m_currentColumn); + tk.setEndPosition(m_currentLine, m_currentColumn); + ADD_TOKEN(tk); +} + +void Lexer::resetSkipWords() +{ + m_words.clear(); +} + +void Lexer::addSkipWord(const QString& word, SkipType skipType, const QString& str) +{ + m_words[ word ] = qMakePair(skipType, str); +} + +void Lexer::skip(int l, int r) +{ + int svCurrentLine = m_currentLine; + int svCurrentColumn = m_currentColumn; + + int count = 0; + + while (!eof()) { + Token tk(m_source); + nextToken(tk); + + if ((int)tk == l) + ++count; + else if ((int)tk == r) + --count; + + if (count == 0) + break; + } + + m_currentLine = svCurrentLine; + m_currentColumn = svCurrentColumn; +} + +QString Lexer::readArgument() +{ + int count = 0; + + QString arg; + + readWhiteSpaces(); + while (!currentChar().isNull()) { + + readWhiteSpaces(); + QChar ch = currentChar(); + + if (ch.isNull() || (!count && (ch == ',' || ch == ')'))) + break; + + Token tk(m_source); + nextToken(tk); + + if (tk == '(') { + ++count; + } else if (tk == ')') { + --count; + } + + if (tk != -1) + arg += tk.text() + ' '; + } + + return arg.trimmed(); +} + +void Lexer::handleDirective(const QString& directive) +{ + m_inPreproc = true; + + bool skip = skipWordsEnabled(); + bool preproc = preprocessorEnabled(); + + setSkipWordsEnabled(false); + setPreprocessorEnabled(false); + + if (directive == "define") { + if (!m_skipping[ m_ifLevel ]) { + Macro m; + processDefine(m); + } + } else if (directive == "else") { + processElse(); + } else if (directive == "elif") { + processElif(); + } else if (directive == "endif") { + processEndif(); + } else if (directive == "if") { + processIf(); + } else if (directive == "ifdef") { + processIfdef(); + } else if (directive == "ifndef") { + processIfndef(); + } else if (directive == "include") { + if (!m_skipping[ m_ifLevel ]) { + processInclude(); + } + } else if (directive == "undef") { + if (!m_skipping[ m_ifLevel ]) { + processUndef(); + } + } + + // skip line + while (!currentChar().isNull() && currentChar() != '\n') { + Token tk(m_source); + nextToken(tk, true); + } + + setSkipWordsEnabled(skip); + setPreprocessorEnabled(preproc); + + m_inPreproc = false; +} + +int Lexer::testIfLevel() +{ + int rtn = !m_skipping[ m_ifLevel++ ]; + m_skipping[ m_ifLevel ] = m_skipping[ m_ifLevel - 1 ]; + return rtn; +} + +int Lexer::macroDefined() +{ + readWhiteSpaces(false); + int startWord = currentPosition(); + readIdentifier(); + HashedString word = m_source.mid(startWord, currentPosition() - startWord); + m_driver->usingString(word); + bool r = m_driver->hasMacro(word); + + if (r) m_driver->usingMacro(m_driver->macro(word)); + + return r; +} + +void Lexer::processDefine(Macro& m) +{ + m.setFileName(m_driver->currentFileName()); + m.setLine(m_currentLine); + m.setColumn(m_currentColumn); + readWhiteSpaces(false); + + int startMacroName = currentPosition(); + readIdentifier(); + QString macroName = m_source.mid(startMacroName, int(currentPosition()-startMacroName)); + m.setName(macroName); + + if (currentChar() == '(') { + m.setHasArguments(true); + nextChar(); + + readWhiteSpaces(false); + + while (!currentChar().isNull() && currentChar() != ')') { + readWhiteSpaces(false); + + int startArg = currentPosition(); + + if (currentChar() == '.' && peekChar() == '.' && peekChar(2) == '.') + nextChar(3); + else + readIdentifier(); + + QString arg = m_source.mid(startArg, int(currentPosition()-startArg)); + + m.addArgument(Macro::Argument(arg)); + + readWhiteSpaces(false); + if (currentChar() != ',') + break; + + nextChar(); // skip ',' + } + + if (currentChar() == ')') + nextChar(); // skip ')' + } + + setPreprocessorEnabled(true); + + QString body; + while (!currentChar().isNull() && currentChar() != '\n') { + + if (currentChar().isSpace()) { + readWhiteSpaces(false); + body += ' '; + } else { + + Token tk(m_source); + nextToken(tk, true); + + //Do not ignore c-style comments, those may be useful in the body, and ignoring them using this check causes problems + if (tk.type() != -1 && (tk.type() != Token_comment || (tk.text().length() >= 2 && tk.text()[1] == '*'))) { + QString s = tk.text(); + body += s; + } + } + } + + m.setBody(body); + m_driver->addMacro(m); +} + +void Lexer::processElse() +{ + if (m_ifLevel == 0) + /// @todo report error + return; + + if (m_ifLevel > 0 && m_skipping[m_ifLevel-1]) + m_skipping[ m_ifLevel ] = m_skipping[ m_ifLevel - 1 ]; + else + m_skipping[ m_ifLevel ] = m_trueTest[ m_ifLevel ]; +} + +void Lexer::processElif() +{ + if (m_ifLevel == 0) + /// @todo report error + return; + + if (!m_trueTest[m_ifLevel]) { + /// @todo implement the correct semantic for elif!! + bool inSkip = m_ifLevel > 0 && m_skipping[ m_ifLevel-1 ]; + m_trueTest[ m_ifLevel ] = macroExpression() != 0; + m_skipping[ m_ifLevel ] = inSkip ? inSkip : !m_trueTest[ m_ifLevel ]; + } else + m_skipping[ m_ifLevel ] = true; +} + +void Lexer::processEndif() +{ + if (m_ifLevel == 0) + /// @todo report error + return; + + m_skipping[ m_ifLevel ] = 0; + m_trueTest[ m_ifLevel-- ] = 0; +} + +void Lexer::processIf() +{ + bool inSkip = m_skipping[ m_ifLevel ]; + + if (testIfLevel()) { +#if 0 + int n; + if ((n = testDefined()) != 0) { + int isdef = macroDefined(); + m_trueTest[ m_ifLevel ] = (n == 1 && isdef) || (n == -1 && !isdef); + } else +#endif + m_trueTest[ m_ifLevel ] = macroExpression() != 0; + m_skipping[ m_ifLevel ] = inSkip ? inSkip : !m_trueTest[ m_ifLevel ]; + } +} + +void Lexer::processIfdef() +{ + bool inSkip = m_skipping[ m_ifLevel ]; + + if (testIfLevel()) { + m_trueTest[ m_ifLevel ] = macroDefined(); + m_skipping[ m_ifLevel ] = inSkip ? inSkip : !m_trueTest[ m_ifLevel ]; + } +} + +void Lexer::processIfndef() +{ + bool inSkip = m_skipping[ m_ifLevel ]; + + if (testIfLevel()) { + m_trueTest[ m_ifLevel ] = !macroDefined(); + m_skipping[ m_ifLevel ] = inSkip ? inSkip : !m_trueTest[ m_ifLevel ]; + } +} + +void Lexer::processInclude() +{ + if (m_skipping[m_ifLevel]) + return; + + readWhiteSpaces(false); + if (!currentChar().isNull()) { + QChar ch = currentChar(); + if (ch == '"' || ch == '<') { + nextChar(); + QChar ch2 = ch == QChar('"') ? QChar('"') : QChar('>'); + + int startWord = currentPosition(); + while (!currentChar().isNull() && currentChar() != ch2) + nextChar(); + if (!currentChar().isNull()) { + QString word = m_source.mid(startWord, int(currentPosition()-startWord)); + m_driver->addDependence(m_driver->currentFileName(), + Dependence(word, ch == '"' ? Dep_Local : Dep_Global)); + nextChar(); + } + } + } +} + +void Lexer::processUndef() +{ + readWhiteSpaces(); + int startWord = currentPosition(); + readIdentifier(); + QString word = m_source.mid(startWord, currentPosition() - startWord); + + Macro m(word, ""); + m.setFileName(m_driver->currentFileName()); + m.setUndef(); + + ///Adds an undef-macro that shadows the previous macro + m_driver->addMacro(m); +} + +int Lexer::macroPrimary() +{ + readWhiteSpaces(false); + int result = 0; + switch (currentChar().toAscii()) { + case '(': + nextChar(); + result = macroExpression(); + if (currentChar() != ')') { + /// @todo report error + return 0; + } + nextChar(); + return result; + + case '+': + case '-': + case '!': + case '~': { + QChar tk = currentChar(); + nextChar(); + int result = macroPrimary(); + if (tk == '-') return -result; + else if (tk == '!') return !result; + else if (tk == '~') return ~result; + } + break; + + default: { + Token tk(m_source); + nextToken(tk, false); + switch (tk.type()) { + case Token_identifier: + if (tk.text() == "defined") { + return macroPrimary(); + } + /// @todo implement + { + HashedString h(tk.text()); + m_driver->usingString(h); + if (m_driver->hasMacro(h)) { + m_driver->usingMacro(m_driver->macro(h)); + Macro &m = m_driver->macro(h); + Lexer lexer(m_driver); + lexer.setSource(m.body()); + int result = lexer.macroExpression(); + return result; + } else { + return false; + } + } + case Token_number_literal: + case Token_char_literal: + return toInt(tk); + default: + break; + } // end switch + + } // end default + + } // end switch + + return 0; +} + +int Lexer::macroMultiplyDivide() +{ + int result = macroPrimary(); + int iresult, op; + for (;;) { + readWhiteSpaces(false); + if (currentChar() == '*') + op = 0; + else if (currentChar() == '/' && !(peekChar() == '*' || peekChar() == '/')) + op = 1; + else if (currentChar() == '%') + op = 2; + else + break; + nextChar(); + iresult = macroPrimary(); + result = op == 0 ? (result * iresult) : + op == 1 ? (iresult == 0 ? 0 : (result / iresult)) : + (iresult == 0 ? 0 : (result % iresult)) ; + } + return result; +} + +int Lexer::macroAddSubtract() +{ + int result = macroMultiplyDivide(); + int iresult, ad; + readWhiteSpaces(false); + while (currentChar() == '+' || currentChar() == '-') { + ad = currentChar() == '+'; + nextChar(); + iresult = macroMultiplyDivide(); + result = ad ? (result+iresult) : (result-iresult); + } + return result; +} + +int Lexer::macroRelational() +{ + int result = macroAddSubtract(); + int iresult; + readWhiteSpaces(false); + while (currentChar() == '<' || currentChar() == '>') { + int lt = currentChar() == '<'; + nextChar(); + if (currentChar() == '=') { + nextChar(); + + iresult = macroAddSubtract(); + result = lt ? (result <= iresult) : (result >= iresult); + } else { + iresult = macroAddSubtract(); + result = lt ? (result < iresult) : (result > iresult); + } + } + + return result; +} + +int Lexer::macroEquality() +{ + int result = macroRelational(); + int iresult, eq; + readWhiteSpaces(false); + while ((currentChar() == '=' || currentChar() == '!') && peekChar() == '=') { + eq = currentChar() == '='; + nextChar(2); + iresult = macroRelational(); + result = eq ? (result==iresult) : (result!=iresult); + } + return result; +} + +int Lexer::macroBoolAnd() +{ + int result = macroEquality(); + readWhiteSpaces(false); + while (currentChar() == '&' && peekChar() != '&') { + nextChar(); + result &= macroEquality(); + } + return result; +} + +int Lexer::macroBoolXor() +{ + int result = macroBoolAnd(); + readWhiteSpaces(false); + while (currentChar() == '^') { + nextChar(); + result ^= macroBoolAnd(); + } + return result; +} + +int Lexer::macroBoolOr() +{ + int result = macroBoolXor(); + readWhiteSpaces(false); + while (currentChar() == '|' && peekChar() != '|') { + nextChar(); + result |= macroBoolXor(); + } + return result; +} + +int Lexer::macroLogicalAnd() +{ + int result = macroBoolOr(); + readWhiteSpaces(false); + while (currentChar() == '&' && peekChar() == '&') { + nextChar(2); + int start = currentPosition(); + result = macroBoolOr() && result; + QString s = m_source.mid(start, currentPosition() - start); + } + return result; +} + +int Lexer::macroLogicalOr() +{ + int result = macroLogicalAnd(); + readWhiteSpaces(false); + while (currentChar() == '|' && peekChar() == '|') { + nextChar(2); + result = macroLogicalAnd() || result; + } + return result; +} + +int Lexer::macroExpression() +{ + readWhiteSpaces(false); + return macroLogicalOr(); +} + +// *IMPORTANT* +// please, don't include lexer.moc here, because Lexer isn't a QObject class!! +// if you have problem while recompiling try to remove cppsupport/.deps, +// cppsupport/Makefile.in and rerun automake/autoconf + diff -Nru umbrello-4.12.3/lib/cppparser/lexer.h umbrello-4.12.90/lib/cppparser/lexer.h --- umbrello-4.12.3/lib/cppparser/lexer.h 1970-01-01 00:00:00.000000000 +0000 +++ umbrello-4.12.90/lib/cppparser/lexer.h 2014-03-05 15:04:09.000000000 +0000 @@ -0,0 +1,880 @@ +/* This file is part of KDevelop + Copyright (C) 2002, 2003 Roberto Raggi + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef LEXER_H +#define LEXER_H + +#include "driver.h" +#include "debug_utils.h" + +#include +#include +#include +#include +#include +#include + +#define CHARTYPE QChar + +enum Type { + Token_eof = 0, + Token_identifier = 1000, + Token_number_literal, + Token_char_literal, + Token_string_literal, + Token_whitespaces, + Token_comment, + Token_preproc, + + Token_assign = 2000, + Token_ptrmem, + Token_ellipsis, + Token_scope, + Token_shift, + Token_eq, + Token_leq, + Token_geq, + Token_incr, + Token_decr, + Token_arrow, + + Token_concat, + + Token_K_DCOP, + Token_k_dcop, + Token_k_dcop_signals, + + Token_Q_OBJECT, + Token_signals, + Token_slots, + Token_emit, + Token_foreach, // qt4 [erbsland] + + Token_and, + Token_and_eq, + Token_asm, + Token_auto, + Token_bitand, + Token_bitor, + Token_bool, + Token_break, + Token_case, + Token_catch, + Token_char, + Token_class, + Token_compl, + Token_const, + Token_const_cast, + Token_continue, + Token_default, + Token_delete, + Token_do, + Token_double, + Token_dynamic_cast, + Token_else, + Token_enum, + Token_explicit, + Token_export, + Token_extern, + Token_false, + Token_float, + Token_for, + Token_friend, + Token_goto, + Token_if, + Token_inline, + Token_int, + Token_long, + Token_mutable, + Token_namespace, + Token_new, + Token_not, + Token_not_eq, + Token_operator, + Token_or, + Token_or_eq, + Token_private, + Token_protected, + Token_public, + Token_register, + Token_reinterpret_cast, + Token_return, + Token_short, + Token_signed, + Token_sizeof, + Token_static, + Token_static_cast, + Token_struct, + Token_switch, + Token_template, + Token_this, + Token_throw, + Token_true, + Token_try, + Token_typedef, + Token_typeid, + Token_typename, + Token_union, + Token_unsigned, + Token_using, + Token_virtual, + Token_void, + Token_volatile, + Token_wchar_t, + Token_while, + Token_xor, + Token_xor_eq +}; + +enum SkipType { + SkipWord, + SkipWordAndArguments +}; + +struct LexerData; + +class Token +{ + Token(const QString &); + Token(int type, int position, int length, const QString& text); + Token(const Token& source); + + Token& operator = (const Token& source); + bool operator == (const Token& token) const; + operator int () const; + +public: + bool isNull() const; + + int type() const; + void setType(int type); + + void getStartPosition(int* line, int* column) const; + void setStartPosition(int line, int column); + void getEndPosition(int* line, int* column) const; + void setEndPosition(int line, int column); + + unsigned int length() const; + void setLength(unsigned int length); + + int position() const; + void setPosition(int position); + + QString text() const; + +private: + int m_type; + int m_position; + int m_length; + int m_startLine; + int m_startColumn; + int m_endLine; + int m_endColumn; + const QString & m_text; + + friend class Lexer; + friend class Parser; +}; // class Token + +class Lexer +{ +public: + Lexer(Driver* driver); + ~Lexer(); + + bool recordComments() const; + void setRecordComments(bool record); + + bool recordWhiteSpaces() const; + void setRecordWhiteSpaces(bool record); + + bool reportWarnings() const; + void setReportWarnings(bool enable); + + bool reportMessages() const; + void setReportMessages(bool enable); + + bool skipWordsEnabled() const; + void setSkipWordsEnabled(bool enabled); + + bool preprocessorEnabled() const; + void setPreprocessorEnabled(bool enabled); + + void resetSkipWords(); + void addSkipWord(const QString& word, SkipType skipType=SkipWord, const QString& str = QString()); + + QString source() const; + void setSource(const QString& source); + + int index() const; + void setIndex(int index); + + //returns the count of lines that wer skipped due to #ifdef's + int skippedLines() const; + + void reset(); + + const Token& tokenAt(int position) const; + const Token& nextToken(); + const Token& lookAhead(int n) const; + + static int toInt(const Token& token); + + int tokenPosition(const Token& token) const; + void getTokenPosition(const Token& token, int* line, int* col); + + int currentLine() const + { + return m_currentLine; + } + int currentColumn() const + { + return m_currentColumn; + } + + inline const CHARTYPE* offset(int offset) const + { + return m_source.unicode() + offset; + } + + inline int getOffset(const QChar* p) const + { + return int(p - (m_source.unicode())); + } + +private: + void setEndPtr(const QChar* c) + { + m_endPtr = c; + if (m_ptr < m_endPtr) + m_currentChar = *m_ptr; + else + m_currentChar = 0; + } + const QChar currentChar() const; + QChar peekChar(int n=1) const; + int currentPosition() const; + + void insertCurrent(const QString& str); + + void tokenize(); + void nextToken(Token& token, bool stopOnNewline=false); + void nextChar(); + void nextChar(int n); + void skip(int l, int r); + void readIdentifier(); + void readWhiteSpaces(bool skipNewLine=true, bool skipOnlyOnce=false); + void readLineComment(); + void readMultiLineComment(); + void readCharLiteral(); + void readStringLiteral(); + void readNumberLiteral(); + + int findOperator3() const; + int findOperator2() const; + bool eof() const; + + // preprocessor (based on an article of Al Stevens on Dr.Dobb's journal) + int testIfLevel(); + int macroDefined(); + QString readArgument(); + + int macroPrimary(); + int macroMultiplyDivide(); + int macroAddSubtract(); + int macroRelational(); + int macroEquality(); + int macroBoolAnd(); + int macroBoolXor(); + int macroBoolOr(); + int macroLogicalAnd(); + int macroLogicalOr(); + int macroExpression(); + + void handleDirective(const QString& directive); + void processDefine(Macro& macro); + void processElse(); + void processElif(); + void processEndif(); + void processIf(); + void processIfdef(); + void processIfndef(); + void processInclude(); + void processUndef(); + +private: + LexerData* d; + Driver* m_driver; + QVector m_tokens; + int m_size; + int m_index; + QString m_source; + const QChar* m_ptr; + const QChar* m_endPtr; + QChar m_currentChar; + bool m_recordComments; + bool m_recordWhiteSpaces; + bool m_startLine; + __gnu_cxx::hash_map< HashedString, QPair > m_words; + + + int m_skippedLines; + int m_currentLine; + int m_currentColumn; + bool m_skipWordsEnabled; + + // preprocessor + QVector m_skipping; + QVector m_trueTest; + int m_ifLevel; + bool m_preprocessorEnabled; + bool m_inPreproc; + + bool m_reportWarnings; + bool m_reportMessages; + +private: + Lexer(const Lexer& source); + void operator = (const Lexer& source); +}; + + +inline Token::Token(const QString & text) + : m_type(-1), + m_position(0), + m_length(0), + m_text(text) +{ +} + +inline Token::Token(int type, int position, int length, const QString& text) + : m_type(type), + m_position(position), + m_length(length), + m_text(text) +{ + DEBUG("Lexer") << type << position << length << text.mid(position, length); +} + +inline Token::Token(const Token& source) + : m_type(source.m_type), + m_position(source.m_position), + m_length(source.m_length), + m_startLine(source.m_startLine), + m_startColumn(source.m_startColumn), + m_endLine(source.m_endLine), + m_endColumn(source.m_endColumn), + m_text(source.m_text) +{ +} + +inline Token& Token::operator = (const Token& source) +{ + m_type = source.m_type; + m_position = source.m_position; + m_length = source.m_length; + m_startLine = source.m_startLine; + m_startColumn = source.m_startColumn; + m_endLine = source.m_endLine; + m_endColumn = source.m_endColumn; +// m_text = source.m_text; + return (*this); +} + +inline Token::operator int () const +{ + return m_type; +} + +inline bool Token::operator == (const Token& token) const +{ + return m_type == token.m_type && + m_position == token.m_position && + m_length == token.m_length && + m_startLine == token.m_startLine && + m_startColumn == token.m_startColumn && + m_endLine == token.m_endLine && + m_endColumn == token.m_endColumn && + m_text == token.m_text; +} + +inline bool Token::isNull() const +{ + return m_type == Token_eof || m_length == 0; +} + +inline int Token::type() const +{ + return m_type; +} + +inline void Token::setType(int type) +{ + m_type = type; +} + +inline int Token::position() const +{ + return m_position; +} + +inline QString Token::text() const +{ + return m_text.mid(m_position, m_length); +} + +inline void Token::setStartPosition(int line, int column) +{ + m_startLine = line; + m_startColumn = column; +} + +inline void Token::setEndPosition(int line, int column) +{ + m_endLine = line; + m_endColumn = column; +} + +inline void Token::getStartPosition(int* line, int* column) const +{ + if (line) *line = m_startLine; + if (column) *column = m_startColumn; +} + +inline void Token::getEndPosition(int* line, int* column) const +{ + if (line) *line = m_endLine; + if (column) *column = m_endColumn; +} + +inline void Token::setPosition(int position) +{ + m_position = position; +} + +inline unsigned int Token::length() const +{ + return m_length; +} + +inline void Token::setLength(unsigned int length) +{ + m_length = length; +} + +inline bool Lexer::recordComments() const +{ + return m_recordComments; +} + +inline void Lexer::setRecordComments(bool record) +{ + m_recordComments = record; +} + +inline bool Lexer::recordWhiteSpaces() const +{ + return m_recordWhiteSpaces; +} + +inline void Lexer::setRecordWhiteSpaces(bool record) +{ + m_recordWhiteSpaces = record; +} + +inline QString Lexer::source() const +{ + return m_source; +} + +inline int Lexer::index() const +{ + return m_index; +} + +inline void Lexer::setIndex(int index) +{ + m_index = index; +} + +inline const Token& Lexer::nextToken() +{ + if (m_index < m_size) + return *m_tokens[ m_index++ ]; + + return *m_tokens[ m_index ]; +} + +inline const Token& Lexer::tokenAt(int n) const +{ + return *m_tokens[ qMin(n, m_size-1) ]; +} + +inline const Token& Lexer::lookAhead(int n) const +{ + Token &t = *m_tokens[ qMin(m_index + n, m_size-1) ]; + DEBUG("Lexer") << t; + return t; +} + +inline int Lexer::tokenPosition(const Token& token) const +{ + return token.position(); +} + +inline void Lexer::nextChar() +{ + if (*m_ptr == '\n') { + ++m_currentLine; + m_currentColumn = 0; + m_startLine = true; + } else { + ++m_currentColumn; + } + ++m_ptr; + + if (m_ptr < m_endPtr) + m_currentChar = *m_ptr; + else + m_currentChar = QChar(); +} + +inline void Lexer::nextChar(int n) +{ + m_currentColumn += n; + m_ptr += n; + + if (m_ptr < m_endPtr) + m_currentChar = *m_ptr; + else + m_currentChar = QChar(); +} + +inline void Lexer::readIdentifier() +{ + while (currentChar().isLetterOrNumber() || currentChar() == '_') + nextChar(); +} + +inline void Lexer::readWhiteSpaces(bool skipNewLine, bool skipOnlyOnce) +{ + while (!currentChar().isNull()) { + QChar ch = currentChar(); + + if (ch == '\n' && !skipNewLine) { + break; + } else if (ch.isSpace()) { + nextChar(); + } else if (m_inPreproc && currentChar() == '\\') { + nextChar(); + readWhiteSpaces(true, true); + } else { + break; + } + if (skipOnlyOnce && ch == '\n') { + skipNewLine = false; + } + } +} + +//little hack for better performance +inline bool isTodo(const QString& txt, int position) +{ + if (txt.length() < position + 4) return false; + return (txt[ position ] == 't' || txt[ position ] == 'T') + && (txt[ position+1 ] == 'o' || txt[ position+1 ] == 'O') + && (txt[ position+2 ] == 'd' || txt[ position+2 ] == 'D') + && (txt[ position+3 ] == 'o' || txt[ position+3 ] == 'O'); +} + +inline bool isFixme(const QString& txt, int position) +{ + if (txt.length() < position + 5) return false; + return (txt[ position ] == 'f' || txt[ position ] == 'F') + && (txt[ position+1 ] == 'i' || txt[ position+1 ] == 'I') + && (txt[ position+2 ] == 'x' || txt[ position+2 ] == 'X') + && (txt[ position+3 ] == 'm' || txt[ position+3 ] == 'M') + && (txt[ position+4 ] == 'e' || txt[ position+4 ] == 'E'); +} + +inline void Lexer::readLineComment() +{ + while (!currentChar().isNull() && currentChar() != '\n') { + if (m_reportMessages && isTodo(m_source, currentPosition())) { + nextChar(4); + QString msg; + int line = m_currentLine; + int col = m_currentColumn; + + while (!currentChar().isNull()) { + if (currentChar() == '*' && peekChar() == '/') + break; + else if (currentChar() == '\n') + break; + + msg += currentChar(); + nextChar(); + } + m_driver->addProblem(m_driver->currentFileName(), Problem(msg, line, col, Problem::Level_Todo)); + } else if (m_reportMessages && isFixme(m_source, currentPosition())) { + nextChar(5); + QString msg; + int line = m_currentLine; + int col = m_currentColumn; + + while (!currentChar().isNull()) { + if (currentChar() == '*' && peekChar() == '/') + break; + else if (currentChar() == '\n') + break; + + msg += currentChar(); + nextChar(); + } + m_driver->addProblem(m_driver->currentFileName(), Problem(msg, line, col, Problem::Level_Fixme)); + } else + nextChar(); + } +} + +inline void Lexer::readMultiLineComment() +{ + while (!currentChar().isNull()) { + if (currentChar() == '*' && peekChar() == '/') { + nextChar(2); + return; + } else if (m_reportMessages && isTodo(m_source, currentPosition())) { + nextChar(4); + QString msg; + int line = m_currentLine; + int col = m_currentColumn; + + while (!currentChar().isNull()) { + if (currentChar() == '*' && peekChar() == '/') + break; + else if (currentChar() == '\n') + break; + msg += currentChar(); + nextChar(); + } + m_driver->addProblem(m_driver->currentFileName(), Problem(msg, line, col, Problem::Level_Todo)); + } else if (m_reportMessages && isFixme(m_source, currentPosition())) { + nextChar(5); + QString msg; + int line = m_currentLine; + int col = m_currentColumn; + + while (!currentChar().isNull()) { + if (currentChar() == '*' && peekChar() == '/') + break; + else if (currentChar() == '\n') + break; + + msg += currentChar(); + nextChar(); + } + m_driver->addProblem(m_driver->currentFileName(), Problem(msg, line, col, Problem::Level_Fixme)); + } else + nextChar(); + } +} + +inline void Lexer::readCharLiteral() +{ + if (currentChar() == '\'') + nextChar(); // skip ' + else if (currentChar() == 'L' && peekChar() == '\'') + nextChar(2); // slip L' + else + return; + + while (!currentChar().isNull()) { + int len = getOffset(m_endPtr) - currentPosition(); + + if (len>=2 && (currentChar() == '\\' && peekChar() == '\'')) { + nextChar(2); + } else if (len>=2 && (currentChar() == '\\' && peekChar() == '\\')) { + nextChar(2); + } else if (currentChar() == '\'') { + nextChar(); + break; + } else { + nextChar(); + } + } +} + +inline void Lexer::readStringLiteral() +{ + if (currentChar() != '"') + return; + + nextChar(); // skip " + + while (!currentChar().isNull()) { + int len = getOffset(m_endPtr) - currentPosition(); + + if (len>=2 && currentChar() == '\\' && peekChar() == '"') { + nextChar(2); + } else if (len>=2 && currentChar() == '\\' && peekChar() == '\\') { + nextChar(2); + } else if (currentChar() == '"') { + nextChar(); + break; + } else { + nextChar(); + } + } +} + +inline void Lexer::readNumberLiteral() +{ + while (currentChar().isLetterOrNumber() || currentChar() == '.') + nextChar(); +} + +inline int Lexer::findOperator3() const +{ + int n = getOffset(m_endPtr) - currentPosition(); + + if (n >= 3) { + QChar ch = currentChar(), ch1=peekChar(), ch2=peekChar(2); + + if (ch == '<' && ch1 == '<' && ch2 == '=') return Token_assign; + else if (ch == '>' && ch1 == '>' && ch2 == '=') return Token_assign; + else if (ch == '-' && ch1 == '>' && ch2 == '*') return Token_ptrmem; + else if (ch == '.' && ch1 == '.' && ch2 == '.') return Token_ellipsis; + } + + return -1; +} + +inline int Lexer::findOperator2() const +{ + int n = getOffset(m_endPtr) - currentPosition(); + + if (n>=2) { + QChar ch = currentChar(), ch1=peekChar(); + + if (ch == ':' && ch1 == ':') return Token_scope; + else if (ch == '.' && ch1 == '*') return Token_ptrmem; + else if (ch == '+' && ch1 == '=') return Token_assign; + else if (ch == '-' && ch1 == '=') return Token_assign; + else if (ch == '*' && ch1 == '=') return Token_assign; + else if (ch == '/' && ch1 == '=') return Token_assign; + else if (ch == '%' && ch1 == '=') return Token_assign; + else if (ch == '^' && ch1 == '=') return Token_assign; + else if (ch == '&' && ch1 == '=') return Token_assign; + else if (ch == '|' && ch1 == '=') return Token_assign; + else if (ch == '<' && ch1 == '<') return Token_shift; + //else if(ch == '>' && ch1 == '>') return Token_shift; + else if (ch == '=' && ch1 == '=') return Token_eq; + else if (ch == '!' && ch1 == '=') return Token_eq; + else if (ch == '<' && ch1 == '=') return Token_leq; + else if (ch == '>' && ch1 == '=') return Token_geq; + else if (ch == '&' && ch1 == '&') return Token_and; + else if (ch == '|' && ch1 == '|') return Token_or; + else if (ch == '+' && ch1 == '+') return Token_incr; + else if (ch == '-' && ch1 == '-') return Token_decr; + else if (ch == '-' && ch1 == '>') return Token_arrow; + else if (ch == '#' && ch1 == '#') return Token_concat; + } + + return -1; +} + +inline bool Lexer::skipWordsEnabled() const +{ + return m_skipWordsEnabled; +} + +inline void Lexer::setSkipWordsEnabled(bool enabled) +{ + m_skipWordsEnabled = enabled; +} + +inline bool Lexer::preprocessorEnabled() const +{ + return m_preprocessorEnabled; +} + +inline void Lexer::setPreprocessorEnabled(bool enabled) +{ + m_preprocessorEnabled = enabled; +} + +inline int Lexer::currentPosition() const +{ + return getOffset(m_ptr); +} + +inline const QChar Lexer::currentChar() const +{ + return m_currentChar; +} + +inline QChar Lexer::peekChar(int n) const +{ + const QChar* p = m_ptr + n; + + if (p < m_endPtr) + return *p; + else + return QChar(); +} + +inline bool Lexer::eof() const +{ + return m_ptr >= m_endPtr; +} + +inline bool Lexer::reportWarnings() const +{ + return m_reportWarnings; +} + +inline void Lexer::setReportWarnings(bool enable) +{ + m_reportWarnings = enable; +} + +inline bool Lexer::reportMessages() const +{ + return m_reportMessages; +} + +inline void Lexer::setReportMessages(bool enable) +{ + m_reportMessages = enable; +} + +inline void Lexer::insertCurrent(const QString& str) +{ + int posi = currentPosition(); + m_source.insert(posi, str); + + m_ptr = offset(posi); + m_endPtr = offset(m_source.length()); + if (m_ptr < m_endPtr) + m_currentChar = *m_ptr; + else + m_currentChar = QChar(); +} + +#endif diff -Nru umbrello-4.12.3/lib/cppparser/lookup.cpp umbrello-4.12.90/lib/cppparser/lookup.cpp --- umbrello-4.12.3/lib/cppparser/lookup.cpp 1970-01-01 00:00:00.000000000 +0000 +++ umbrello-4.12.90/lib/cppparser/lookup.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -0,0 +1,41 @@ +/* This file is part of KDevelop + Copyright (C) 2005 Tobias Erbsland + Copyright (C) 2002, 2003 Roberto Raggi + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include "lookup.h" + +int Lookup::find(const HashedString& s) +{ + KeywordMap::const_iterator it = keywords().find(s); + if (it == keywords().end()) + return -1; + return static_cast((*it).second); +} + +const Lookup::KeywordMap& Lookup::keywords() +{ + static KeywordMap keywords; + + if (keywords.empty()) { +#include "keywords.h" + } + + return keywords; +} + diff -Nru umbrello-4.12.3/lib/cppparser/lookup.h umbrello-4.12.90/lib/cppparser/lookup.h --- umbrello-4.12.3/lib/cppparser/lookup.h 1970-01-01 00:00:00.000000000 +0000 +++ umbrello-4.12.90/lib/cppparser/lookup.h 2014-03-05 15:04:09.000000000 +0000 @@ -0,0 +1,46 @@ +/* This file is part of KDevelop + Copyright (C) 2005 Tobias Erbsland + Copyright (C) 2002, 2003 Roberto Raggi + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef _LOOKUP_H_ +#define _LOOKUP_H_ + +#include +#include + +#include "lexer.h" +#include +#include + +/** +* @short Fast keyword lookup. +*/ +class Lookup +{ +public: + typedef __gnu_cxx::hash_map KeywordMap; + /** + * Find an entry in the table, and return its value + */ + static int find(const HashedString& s); + + static const KeywordMap& keywords(); +}; + +#endif diff -Nru umbrello-4.12.3/lib/cppparser/macro.h umbrello-4.12.90/lib/cppparser/macro.h --- umbrello-4.12.3/lib/cppparser/macro.h 1970-01-01 00:00:00.000000000 +0000 +++ umbrello-4.12.90/lib/cppparser/macro.h 2014-03-05 15:04:09.000000000 +0000 @@ -0,0 +1,502 @@ +/*************************************************************************** + copyright : (C) 2006 by David Nolden + email : david.nolden.kdevelop@art-master.de +***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef MACRO_H +#define MACRO_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef signed char Q_INT8; + +//This files should be renamed to something like "helpers.h" + +/** + * Encapsulates a problem in a piece of source code. + */ +class Problem +{ +public: + enum { + Level_Error = 0, ///< Indicates an error that will prevent the code from compiling + Level_Warning, ///< Indicates a warning + Level_Todo, ///< Indicates there is still something left to do + Level_Fixme ///< Indicates that something needs to be fixed + }; + +public: + Problem() {} + Problem(const Problem& source) + : m_text(source.m_text), m_line(source.m_line), + m_column(source.m_column), m_level(source.m_level), m_file(source.m_file) {} + Problem(const QString& text, int line, int column, int level = Level_Error) + : m_text(text), m_line(line), m_column(column), m_level(level) {} + + Problem(const Problem& source, bool /*threadSafeClone*/) + : m_text(QString::fromUtf8(source.m_text.toUtf8().data())), m_line(source.m_line), + m_column(source.m_column), m_level(source.m_level), m_file(QString::fromUtf8(source.m_file.toUtf8().data())) {} + + Problem& operator = (const Problem& source) + { + m_text = source.m_text; + m_line = source.m_line; + m_column = source.m_column; + m_level = source.m_level; + m_file = source.m_file; + return (*this); + } + + void setFileName(const QString& fileName) + { + m_file = fileName; + } + + bool operator == (const Problem& p) const + { + return m_text == p.m_text && m_line == p.m_line && m_column == p.m_column && m_level == p.m_level && m_file == p.m_file; + } + + /** Get the filename in which the problem was encountered */ + QString fileName() const + { + return m_file; + } + + /** Get the text for the problem */ + QString text() const + { + return m_text; + } + /** Get the line number of the problem */ + int line() const + { + return m_line; + } + /** Get the column of the problem */ + int column() const + { + return m_column; + } + /** + * Get the seriousness of the problem. There are four possibilities: + * \li Error + * \li Warning + * \li Todo + * \li Fixme + */ + int level() const + { + return m_level; + } + +private: + QString m_text; + int m_line; + int m_column; + int m_level; + QString m_file; +}; + + +/** + * A datatype that represents a preprocessor macro. + * Most of the functions in this class need to be inline, so we do not have to import cppparser to many modules. The other solution would be moving macro into interfaces. + */ +class Macro +{ +public: + typedef QString Argument; + +public: + Macro(bool hasArguments = false) : m_idHashValid(false), m_valueHashValid(false), m_line(0), m_column(0), m_hasArguments(hasArguments), m_isUndefMacro(false) {} + Macro(const QString &n, const QString &b) : m_idHashValid(false), m_valueHashValid(false), m_name(n), m_line(0), m_column(0), m_body(b), m_hasArguments(false), m_isUndefMacro(false) {} + + //Sorts the macros by their hash-value, then by their name. + struct NameArgCompare { + bool operator () (const Macro& lhs, const Macro& rhs) const + { + size_t lhash = lhs.idHash(); + size_t rhash = rhs.idHash(); + if (lhash < rhash) return true; + else if (lhash > rhash) return false; + + int df = lhs.m_name.compare(rhs.m_name); + if (df < 0) + return true; + if (df == 0) { + if (!lhs.m_hasArguments && rhs.m_hasArguments) { + return true; + } else if (lhs.m_hasArguments == rhs.m_hasArguments) { + return lhs.m_argumentList.count() < rhs.m_argumentList.count(); + + } else { + return false; + } + } + return false; + } + }; + struct NameCompare { + bool operator () (const Macro& lhs, const Macro& rhs) const + { + size_t lhash = lhs.idHash(); + size_t rhash = rhs.idHash(); + if (lhash < rhash) return true; + else if (lhash > rhash) return false; + + int df = lhs.m_name.compare(rhs.m_name); + return df < 0; + } + }; + + struct NameArgHash { + size_t operator () (const Macro& macro) const + { + return macro.idHash(); + } + }; + + struct NameArgEqual { + bool operator () (const Macro& lhs, const Macro& rhs) const + { + int df = lhs.m_name.compare(rhs.m_name); + if (df == 0) { + if (lhs.m_hasArguments != rhs.m_hasArguments) { + return false; + } else { + if (lhs.m_argumentList.count() != rhs.m_argumentList.count()) return false; + /*QStringList::const_iterator it2 = rhs.m_argumentList.begin(); + for(QStringList::const_iterator it = lhs.m_argumentList.begin(); it != lhs.m_argumentList.end();) { + if(*it != *it2) return false; + + ++it; + ++it2; + }*/ + return true; + + } + } + return false; + } + }; + + Macro(const Macro& source) + : m_idHashValid(source.m_idHashValid), m_valueHashValid(source.m_valueHashValid), m_idHash(source.m_idHash), m_valueHash(source.m_valueHash), m_name(source.m_name), + m_fileName(source.m_fileName), + m_line(source.m_line), + m_column(source.m_column), + m_body(source.m_body), + m_hasArguments(source.m_hasArguments), + m_argumentList(source.m_argumentList), m_isUndefMacro(source.m_isUndefMacro) {} + + Macro& operator = (const Macro& source) + { + m_idHashValid = source.m_idHashValid; + m_valueHashValid = source.m_valueHashValid; + m_idHash = source.m_idHash; + m_valueHash = source.m_valueHash; + m_name = source.m_name; + m_fileName = source.m_fileName; + m_line = source.m_line; + m_column = source.m_column; + m_body = source.m_body; + m_hasArguments = source.m_hasArguments; + m_argumentList = source.m_argumentList; + m_isUndefMacro = source.m_isUndefMacro; + return *this; + } + + bool operator == (const Macro& source) const + { + if (!m_idHashValid || !m_valueHashValid) computeHash(); + if (!source.m_idHashValid || !source.m_valueHashValid) source.computeHash(); + + if (m_idHash != source.m_idHash) return false; + if (m_valueHash != source.m_valueHash) return false; + + return m_name == source.m_name && + m_fileName == source.m_fileName && + m_body == source.m_body && + m_hasArguments == source.m_hasArguments && + m_argumentList == source.m_argumentList && m_isUndefMacro == source.m_isUndefMacro; + } + + void read(QDataStream& stream) + { + Q_INT8 i; + stream >> i; + m_idHashValid = i; + stream >> i; + m_valueHashValid = i; + stream >> i; + m_hasArguments = i; + + stream >> m_idHash; + stream >> m_valueHash; + stream >> m_name; + stream >> m_line; + stream >> m_column; + stream >> m_body; + stream >> m_fileName; + stream >> m_argumentList; + } + + void write(QDataStream& stream) const + { + Q_INT8 i; + i = m_idHashValid; + stream << i; + i = m_valueHashValid; + stream << i; + i = m_hasArguments; + stream << i; + + stream << m_idHash; + stream << m_valueHash; + stream << m_name; + stream << m_line; + stream << m_column; + stream << m_body; + stream << m_fileName; + stream << m_argumentList; + } + + /** Get the name for this macro */ + QString name() const + { + return m_name; + } + /** Set the name for this macro */ + void setName(const QString& name) + { + m_name = name; + invalidateHash(); + } + + /** Get the file name that contains this macro */ + QString fileName() const + { + return m_fileName; + } + /** Set the file name that contains this macro */ + void setFileName(const QString& fileName) + { + m_fileName = fileName; + invalidateHash(); + } + + /** Get the line the macro is defined on */ + int line() const + { + return m_line; + } + /** Set the line the macro is defined on */ + void setLine(int line) + { + m_line = line; + } + + /** Get the column the macro starts at */ + int column() const + { + return m_column; + } + /** Set the column the macro starts at */ + void setColumn(int column) + { + m_column = column; + } + + /** Get the body of the macro */ + QString body() const + { + return m_body; + } + /** Set the body of the macro */ + void setBody(const QString& body) + { + m_body = body; + invalidateHash(); + } + + /** This is used so the lexer does not have to remove macros that should really stay(they are just temporarily shadowed by an isUndef-macro */ + bool isUndef() const + { + return m_isUndefMacro; + }; + + void setUndef() + { + m_isUndefMacro = true; + invalidateHash(); + }; + + /** Check whether the macro has arguments that are passed to it */ + bool hasArguments() const + { + return m_hasArguments; + } + void setHasArguments(bool hasArguments) + { + m_hasArguments = hasArguments; + invalidateHash(); + } + /** Get a list of arguments passed to this macro */ + QList argumentList() const + { + return m_argumentList; + } + + /** Clear the list of arguments this macro has */ + void clearArgumentList() + { + m_argumentList.clear(); + m_hasArguments = false; + invalidateHash(); + } + /** Add an argument to this macro */ + void addArgument(const Argument& argument) + { + m_argumentList << argument; + } + /** Add a list of arguments to this macro */ + void addArgumentList(const QList& arguments) + { + m_argumentList += arguments; + invalidateHash(); + } + + ///This hash respects macro-name and argument-count + size_t idHash() const + { + if (!m_idHashValid) computeHash(); + return m_idHash; + } + + ///This hash respects body and if it is an undef-macro + size_t valueHash() const + { + if (!m_valueHashValid) computeHash(); + return m_valueHash; + } + +private: + inline void invalidateHash() const + { + m_idHashValid = m_valueHashValid = false; + } + + void computeHash() const + { + m_idHash = 7 * (HashedString::hashString(m_name)); + int a = 1; + //m_idHash += 31 * m_argumentList.count(); + + m_valueHash = 27 * (HashedString::hashString(m_body) + (m_isUndefMacro ? 1 : 0)); + + for (QList::const_iterator it = m_argumentList.begin(); it != m_argumentList.end(); ++it) { + a *= 19; + m_valueHash += a * HashedString::hashString(*it); + } + m_valueHashValid = true; + m_idHashValid = true; + } + + mutable bool m_idHashValid; + mutable bool m_valueHashValid; + mutable size_t m_idHash; //Hash that represents the ids of all macros + mutable size_t m_valueHash; //Hash that represents the values of all macros + + QString m_name; + QString m_fileName; + int m_line; + int m_column; + QString m_body; + bool m_hasArguments; + QStringList m_argumentList; //While identification, only the count plays a role, not the values. + bool m_isUndefMacro; + friend class NameCompare; + friend class NameArgEqual; +}; + +class MacroSet +{ +public: + //typedef __gnu_cxx::hash_set< Macro, Macro::NameArgHash, Macro::NameArgEqual > Macros; + typedef std::set< Macro, Macro::NameCompare > Macros; + MacroSet() : m_idHashValid(false), m_valueHashValid(false) + { + } + + void addMacro(const Macro& macro); + + void read(QDataStream& stream) + { + //stream >> m_idHashValid >> m_idHash >> m_valueHashValid >> m_valueHash; + m_idHashValid = false; + m_valueHashValid = false; + int cnt; + stream >> cnt; + m_usedMacros.clear(); + Macro m; + for (int a = 0; a < cnt; a++) { + m.read(stream); + m_usedMacros.insert(m); + } + } + + void write(QDataStream& stream) const + { + //stream << m_idHashValid << m_idHash << m_valueHashValid << m_valueHash; + stream << int(m_usedMacros.size()); + for (Macros::const_iterator it = m_usedMacros.begin(); it != m_usedMacros.end(); ++it) { + (*it).write(stream); + } + } + + bool hasMacro(const QString& name) const; + bool hasMacro(const HashedString& name) const; + Macro macro(const QString& name) const; + + size_t idHash() const; + size_t valueHash() const; + + const Macros& macros() const + { + return m_usedMacros; + } + + void merge(const MacroSet& macros); +private: + void computeHash() const; + Macros m_usedMacros; + mutable bool m_idHashValid; + mutable bool m_valueHashValid; + mutable size_t m_idHash; //Hash that represents the ids of all macros + mutable size_t m_valueHash; //Hash that represents the values of all macros + + friend class Driver; +}; + +#endif diff -Nru umbrello-4.12.3/lib/cppparser/parser.cpp umbrello-4.12.90/lib/cppparser/parser.cpp --- umbrello-4.12.3/lib/cppparser/parser.cpp 1970-01-01 00:00:00.000000000 +0000 +++ umbrello-4.12.90/lib/cppparser/parser.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -0,0 +1,4317 @@ +/* This file is part of KDevelop + Copyright (C) 2002, 2003 Roberto Raggi + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +// c++ support +#include "driver.h" +#include "lexer.h" +#include "parser.h" +#include "errors.h" + +// qt +#include +#include + +#include +#include + +using namespace std; + +DEBUG_REGISTER_DISABLED(Parser) + +#define ADVANCE(tk, descr) \ +{ \ + const Token& token = lex->lookAhead(0); \ + if(token != tk){ \ + reportError(i18n("'%1' expected found '%2'").arg(descr).arg(token.text())); \ + return false; \ + } \ + nextToken(); \ +} + +#define ADVANCE_NR(tk, descr) \ +{ \ + const Token& token = lex->lookAhead(0); \ + if(token != tk){ \ + reportError(i18n("'%1' expected found '%2'").arg(descr).arg(token.text())); \ + } \ + else \ + nextToken(); \ +} + +#define CHECK(tk, descr) \ +{ \ + const Token& token = lex->lookAhead(0); \ + if(token != tk){ \ + return false; \ + } \ + nextToken(); \ +} + +#define MATCH(tk, descr) \ +{ \ + const Token& token = lex->lookAhead(0); \ + if(token != tk){ \ + reportError(Errors::SyntaxError); \ + return false; \ + } \ +} + + + +#define UPDATE_POS(node, start, end) \ +{ \ + int line, col; \ + const Token &a = lex->tokenAt(start); \ + const Token &b = lex->tokenAt(end!=start ? end-1 : end); \ + a.getStartPosition(&line, &col); \ + (node)->setStartPosition(line, col); \ + b.getEndPosition(&line, &col); \ + (node)->setEndPosition(line, col); \ + if((node)->nodeType() == NodeType_Generic) { \ + if ((start) == (end) || (end) == (start)+1) \ + (node)->setSlice(lex->source(), a.position(), a.length()); \ + else \ + (node)->setText(toString((start),(end))); \ + } \ +} + +#define AST_FROM_TOKEN(node, tk) \ + AST::Node node = CreateNode(); \ + UPDATE_POS(node, (tk), (tk)+1); + + +//@todo remove me +enum { + OBJC_CLASS, + OBJC_PROTOCOL, + OBJC_ALIAS +}; + +struct ParserPrivateData { + ParserPrivateData() + {} +}; + +Parser::Parser(Driver* driver, Lexer* lexer) + : m_driver(driver), + lex(lexer), m_problems(0) +{ + d = new ParserPrivateData(); + + m_maxProblems = 5; + objcp = false; +} + +Parser::~Parser() +{ + delete d; + d = 0; +} + +bool Parser::reportError(const Error& err) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::reportError()" << endl; + if (m_problems < m_maxProblems) { + ++m_problems; + int line=0, col=0; + const Token& token = lex->lookAhead(0); + lex->getTokenPosition(token, &line, &col); + + QString s = lex->lookAhead(0).text(); + s = s.left(30).trimmed(); + if (s.isEmpty()) + s = i18n(""); + + m_driver->addProblem(m_driver->currentFileName(), Problem(err.text.arg(s), line, col)); + } + + return true; +} + +bool Parser::reportError(const QString& msg) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::reportError()" << endl; + if (m_problems < m_maxProblems) { + ++m_problems; + int line=0, col=0; + const Token& token = lex->lookAhead(0); + lex->getTokenPosition(token, &line, &col); + + m_driver->addProblem(m_driver->currentFileName(), Problem(msg, line, col)); + } + + return true; +} + +void Parser::syntaxError() +{ + (void) reportError(Errors::SyntaxError); +} + +bool Parser::skipUntil(int token) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::skipUntil()" << endl; + while (!lex->lookAhead(0).isNull()) { + if (lex->lookAhead(0) == token) + return true; + + nextToken(); + } + + return false; +} + +bool Parser::skipUntilDeclaration() +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::skipUntilDeclaration()" << endl; + clearComment(); + + while (!lex->lookAhead(0).isNull()) { + + switch (lex->lookAhead(0)) { + case ';': + case '~': + case Token_scope: + case Token_identifier: + case Token_operator: + case Token_char: + case Token_wchar_t: + case Token_bool: + case Token_short: + case Token_int: + case Token_long: + case Token_signed: + case Token_unsigned: + case Token_float: + case Token_double: + case Token_void: + case Token_extern: + case Token_namespace: + case Token_using: + case Token_typedef: + case Token_asm: + case Token_template: + case Token_export: + + case Token_const: // cv + case Token_volatile: // cv + + case Token_public: + case Token_protected: + case Token_private: + case Token_signals: // Qt + case Token_slots: // Qt + return true; + + default: + nextToken(); + } + } + + return false; +} + +bool Parser::skipUntilStatement() +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::skipUntilStatement() -- token = " << lex->lookAhead(0).text() << endl; + + while (!lex->lookAhead(0).isNull()) { + switch (lex->lookAhead(0)) { + case ';': + case '{': + case '}': + case Token_const: + case Token_volatile: + case Token_identifier: + case Token_case: + case Token_default: + case Token_if: + case Token_switch: + case Token_while: + case Token_do: + case Token_for: + case Token_break: + case Token_continue: + case Token_return: + case Token_goto: + case Token_try: + case Token_catch: + case Token_throw: + case Token_char: + case Token_wchar_t: + case Token_bool: + case Token_short: + case Token_int: + case Token_long: + case Token_signed: + case Token_unsigned: + case Token_float: + case Token_double: + case Token_void: + case Token_class: + case Token_struct: + case Token_union: + case Token_enum: + case Token_scope: + case Token_template: + case Token_using: + return true; + + default: + nextToken(); + } + } + + return false; +} + +bool Parser::skip(int l, int r) +{ + int count = 0; + while (!lex->lookAhead(0).isNull()) { + int tk = lex->lookAhead(0); + + if (tk == l) + ++count; + else if (tk == r) + --count; + else if (l != '{' && (tk == '{' || tk == '}' || tk == ';')) + return false; + + if (count == 0) + return true; + + nextToken(); + } + + return false; +} + +bool Parser::skipCommaExpression(AST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::skipCommaExpression()" << endl; + + int start = lex->index(); + + AST::Node expr; + if (!skipExpression(expr)) + return false; + + while (lex->lookAhead(0) == ',') { + nextToken(); + + if (!skipExpression(expr)) { + reportError(i18n("expression expected")); + return false; + } + } + + AST::Node ast = CreateNode(); + UPDATE_POS(ast, start, lex->index()); + node = ast; + + return true; +} + +bool Parser::skipExpression(AST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::skipExpression()" << endl; + + int start = lex->index(); + + while (!lex->lookAhead(0).isNull()) { + int tk = lex->lookAhead(0); + + switch (tk) { + case '(': + skip('(', ')'); + nextToken(); + break; + + case '[': + skip('[', ']'); + nextToken(); + break; + +#if 0 + case Token_identifier: + nextToken(); + if (lex->lookAhead(0) == Token_identifier) + return true; + break; +#endif + + case ';': + case ',': + case ']': + case ')': + case '{': + case '}': + case Token_case: + case Token_default: + case Token_if: + case Token_while: + case Token_do: + case Token_for: + case Token_break: + case Token_continue: + case Token_return: + case Token_goto: { + AST::Node ast = CreateNode(); + UPDATE_POS(ast, start, lex->index()); + node = ast; + } + return true; + + default: + nextToken(); + } + } + + return false; +} + +bool Parser::parseName(NameAST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseName()" << endl; + + GroupAST::Node winDeclSpec; + parseWinDeclSpec(winDeclSpec); + + int start = lex->index(); + + NameAST::Node ast = CreateNode(); + + if (lex->lookAhead(0) == Token_scope) { + ast->setGlobal(true); + nextToken(); + } + + int idx = lex->index(); + + while (true) { + ClassOrNamespaceNameAST::Node n; + if (!parseUnqualifiedName(n)) { + return false; + } + + if (lex->lookAhead(0) == Token_scope) { + nextToken(); + ast->addClassOrNamespaceName(n); + if (lex->lookAhead(0) == Token_template) + nextToken(); /// skip optional template #### @todo CHECK + } else { + ast->setUnqualifiedName(n); + break; + } + } + + if (idx == lex->index()) + return false; + + UPDATE_POS(ast, start, lex->index()); + node = ast; + + return true; +} + +bool Parser::parseTranslationUnit(TranslationUnitAST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseTranslationUnit()" << endl; + + int start = lex->index(); + + m_problems = 0; + TranslationUnitAST::Node tun = CreateNode(); + node = tun; + if (lex->lookAhead(0) == Token_comment) { + node->setComment(lex->lookAhead(0).text()); + nextToken(); + } + + while (!lex->lookAhead(0).isNull()) { + DeclarationAST::Node def; + int startDecl = lex->index(); + if (!parseDeclaration(def)) { + // error recovery + if (startDecl == lex->index()) + nextToken(); // skip at least one token + skipUntilDeclaration(); + } + node->addDeclaration(def); + } + + UPDATE_POS(node, start, lex->index()); + + // force (0,0) as start position + node->setStartPosition(0, 0); + + return m_problems == 0; +} + +bool Parser::parseDeclaration(DeclarationAST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseDeclaration()" << endl; + + int start = lex->index(); + + switch (lex->lookAhead(0)) { + + case ';': + nextToken(); + return true; + + case Token_extern: + return parseLinkageSpecification(node); + + case Token_namespace: + return parseNamespace(node); + + case Token_using: + return parseUsing(node); + + case Token_typedef: + return parseTypedef(node); + + case Token_asm: + return parseAsmDefinition(node); + + case Token_template: + case Token_export: + return parseTemplateDeclaration(node); + + default: { + // lex->setIndex(start); + + if (objcp && parseObjcDef(node)) + return true; + + lex->setIndex(start); + + GroupAST::Node storageSpec; + parseStorageClassSpecifier(storageSpec); + + GroupAST::Node cv; + parseCvQualify(cv); + + TypeSpecifierAST::Node spec; + AST::Node declarator; + if (parseEnumSpecifier(spec) || parseClassSpecifier(spec)) { + int line, c; + spec->getEndPosition(&line, &c); + spec->setCvQualify(cv); + + GroupAST::Node cv2; + parseCvQualify(cv2); + spec->setCv2Qualify(cv2); + + InitDeclaratorListAST::Node declarators; + parseInitDeclaratorList(declarators); + + SimpleDeclarationAST::Node ast = CreateNode(); + + ADVANCE(';', ";"); + + preparseLineComments(line); + + ast->setComment(m_commentStore.getCommentInRange(line)); + + ast->setStorageSpecifier(storageSpec); + ast->setTypeSpec(spec); + ast->setInitDeclaratorList(declarators); + UPDATE_POS(ast, start, lex->index()); + node = ast; + + return true; + } + + lex->setIndex(start); + return parseDeclarationInternal(node); + } + + } // end switch +} + +bool Parser::parseLinkageSpecification(DeclarationAST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseLinkageSpecification()" << endl; + + int start = lex->index(); + + if (lex->lookAhead(0) != Token_extern) { + return false; + } + nextToken(); + + LinkageSpecificationAST::Node ast = CreateNode(); + + int startExternType = lex->index(); + if (lex->lookAhead(0) == Token_string_literal) { + nextToken(); + AST::Node externType = CreateNode(); + UPDATE_POS(externType, startExternType, lex->index()); + + ast->setExternType(externType); + } + + if (lex->lookAhead(0) == '{') { + LinkageBodyAST::Node linkageBody; + parseLinkageBody(linkageBody); + ast->setLinkageBody(linkageBody); + } else { + DeclarationAST::Node decl; + if (!parseDeclaration(decl)) { + reportError(i18n("Declaration syntax error")); + } + ast->setDeclaration(decl); + } + + UPDATE_POS(ast, start, lex->index()); + + node = ast; + + return true; +} + +bool Parser::parseLinkageBody(LinkageBodyAST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseLinkageBody()" << endl; + + int start = lex->index(); + + if (lex->lookAhead(0) != '{') { + return false; + } + nextToken(); + + LinkageBodyAST::Node lba = CreateNode(); + node = lba; + + while (!lex->lookAhead(0).isNull()) { + int tk = lex->lookAhead(0); + + if (tk == '}') + break; + + DeclarationAST::Node def; + int startDecl = lex->index(); + if (parseDeclaration(def)) { + node->addDeclaration(def); + } else { + // error recovery + if (startDecl == lex->index()) + nextToken(); // skip at least one token + skipUntilDeclaration(); + } + } + + clearComment(); + + if (lex->lookAhead(0) != '}') { + reportError(i18n("} expected")); + } else + nextToken(); + + UPDATE_POS(node, start, lex->index()); + return true; +} + +bool Parser::parseNamespace(DeclarationAST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseNamespace()" << endl; + + int start = lex->index(); + + if (lex->lookAhead(0) != Token_namespace) { + return false; + } + nextToken(); + + int startNamespaceName = lex->index(); + if (lex->lookAhead(0) == Token_identifier) { + nextToken(); + } + AST::Node namespaceName = CreateNode(); + UPDATE_POS(namespaceName, startNamespaceName, lex->index()); + + if (lex->lookAhead(0) == '=') { + // namespace alias + nextToken(); + + NameAST::Node name; + if (parseName(name)) { + ADVANCE(';', ";"); + + NamespaceAliasAST::Node ast = CreateNode(); + ast->setNamespaceName(namespaceName); + ast->setAliasName(name); + UPDATE_POS(ast, start, lex->index()); + node = ast; + return true; + } else { + reportError(i18n("namespace expected")); + return false; + } + } else if (lex->lookAhead(0) != '{') { + reportError(i18n("{ expected")); + return false; + } + + NamespaceAST::Node ast = CreateNode(); + ast->setNamespaceName(namespaceName); + + LinkageBodyAST::Node linkageBody; + parseLinkageBody(linkageBody); + + ast->setLinkageBody(linkageBody); + UPDATE_POS(ast, start, lex->index()); + node = ast; + + return true; +} + +bool Parser::parseUsing(DeclarationAST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseUsing()" << endl; + + int start = lex->index(); + + if (lex->lookAhead(0) != Token_using) { + return false; + } + nextToken(); + + if (lex->lookAhead(0) == Token_namespace) { + if (!parseUsingDirective(node)) { + return false; + } + UPDATE_POS(node, start, lex->index()); + return true; + } + + UsingAST::Node ast = CreateNode(); + + int startTypeName = lex->index(); + if (lex->lookAhead(0) == Token_typename) { + nextToken(); + AST::Node tn = CreateNode(); + UPDATE_POS(tn, startTypeName, lex->index()); + ast->setTypeName(tn); + } + + NameAST::Node name; + if (!parseName(name)) + return false; + + ast->setName(name); + + ADVANCE(';', ";"); + + UPDATE_POS(ast, start, lex->index()); + node = ast; + + return true; +} + +bool Parser::parseUsingDirective(DeclarationAST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseUsingDirective()" << endl; + + int start = lex->index(); + + if (lex->lookAhead(0) != Token_namespace) { + return false; + } + nextToken(); + + NameAST::Node name; + if (!parseName(name)) { + reportError(i18n("Namespace name expected")); + return false; + } + + ADVANCE(';', ";"); + + UsingDirectiveAST::Node ast = CreateNode(); + ast->setName(name); + UPDATE_POS(ast, start, lex->index()); + node = ast; + + return true; +} + + +bool Parser::parseOperatorFunctionId(AST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseOperatorFunctionId()" << endl; + + int start = lex->index(); + + if (lex->lookAhead(0) != Token_operator) { + return false; + } + nextToken(); + + AST::Node op; + if(parseOperator(op)){ + AST::Node asn = CreateNode(); + node = asn; + UPDATE_POS(node, start, lex->index()); + if (node->text() == "operator > >") + node->setText("operator >>"); + return true; + } else { + // parse cast operator + GroupAST::Node cv; + parseCvQualify(cv); + + TypeSpecifierAST::Node spec; + if (!parseSimpleTypeSpecifier(spec)) { + syntaxError(); + return false; + } + spec->setCvQualify(cv); + + GroupAST::Node cv2; + parseCvQualify(cv2); + spec->setCv2Qualify(cv2); + + AST::Node ptrOp; + while (parsePtrOperator(ptrOp)) + ; + + AST::Node asn = CreateNode(); + node = asn; + UPDATE_POS(node, start, lex->index()); + return true; + } +} + +bool Parser::parseTemplateArgumentList(TemplateArgumentListAST::Node& node, bool reportError) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseTemplateArgumentList()" << endl; + + int start = lex->index(); + + TemplateArgumentListAST::Node ast = CreateNode(); + + AST::Node templArg; + if (!parseTemplateArgument(templArg)) + return false; + ast->addArgument(templArg); + + while (lex->lookAhead(0) == ',') { + nextToken(); + + if (!parseTemplateArgument(templArg)) { + if (reportError) { + syntaxError(); + break; + } else + return false; + } + ast->addArgument(templArg); + } + + UPDATE_POS(ast, start, lex->index()); + node = ast; + + return true; +} + +bool Parser::parseTypedef(DeclarationAST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseTypedef()" << endl; + + int start = lex->index(); + + if (lex->lookAhead(0) != Token_typedef) { + return false; + } + nextToken(); + + TypeSpecifierAST::Node spec; + if (!parseTypeSpecifierOrClassSpec(spec)) { + reportError(i18n("Need a type specifier to declare")); + return false; + } + + InitDeclaratorListAST::Node declarators; + if (!parseInitDeclaratorList(declarators)) { + //reportError(i18n("Need an identifier to declare")); + //return false; + } + + TypedefAST::Node ast = CreateNode(); + + + if (comment()) { + ast->setComment(comment()); + clearComment(); + + preparseLineComments(currentLine()); + + if (comment()) { + ast->addComment(comment()); + clearComment(); + } + } + + ADVANCE(';', ";"); + + ast->setTypeSpec(spec); + ast->setInitDeclaratorList(declarators); + UPDATE_POS(ast, start, lex->index()); + node = ast; + + return true; +} + +bool Parser::parseAsmDefinition(DeclarationAST::Node& /*node*/) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseAsmDefinition()" << endl; + + ADVANCE(Token_asm, "asm"); + + GroupAST::Node cv; + parseCvQualify(cv); + + skip('(', ')'); + ADVANCE(')', ")"); + ADVANCE(';', ';'); + + return true; +} + +bool Parser::parseTemplateDeclaration(DeclarationAST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseTemplateDeclaration()" << endl; + + int start = lex->index(); + + AST::Node exp; + + int startExport = lex->index(); + if (lex->lookAhead(0) == Token_export) { + nextToken(); + AST::Node n = CreateNode(); + UPDATE_POS(n, startExport, lex->index()); + exp = n; + } + + if (lex->lookAhead(0) != Token_template) { + return false; + } + nextToken(); + + TemplateParameterListAST::Node params; + if (lex->lookAhead(0) == '<') { + nextToken(); + parseTemplateParameterList(params); + + ADVANCE('>', ">"); + } + + DeclarationAST::Node def; + if (!parseDeclaration(def)) { + reportError(i18n("expected a declaration")); + } + + TemplateDeclarationAST::Node ast = CreateNode(); + ast->setExported(exp); + ast->setTemplateParameterList(params); + ast->setDeclaration(def); + UPDATE_POS(ast, start, lex->index()); + node = ast; + + return true; +} + +bool Parser::parseOperator(AST::Node& /*node*/) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseOperator()" << endl; + QString text = lex->lookAhead(0).text(); + + switch (lex->lookAhead(0)) { + case Token_new: + case Token_delete: + nextToken(); + if (lex->lookAhead(0) == '[' && lex->lookAhead(1) == ']') { + nextToken(); + nextToken(); + text += "[]"; + } + return true; + + case '+': + case '-': + case '*': + case '/': + case '%': + case '^': + case '&': + case '|': + case '~': + case '!': + case '=': + case '<': + case '>': + case ',': + case Token_assign: + case Token_shift: + case Token_eq: + case Token_not_eq: + case Token_leq: + case Token_geq: + case Token_and: + case Token_or: + case Token_incr: + case Token_decr: + case Token_ptrmem: + case Token_arrow: + nextToken(); + if (lex->lookAhead(0) == '>') + nextToken(); + return true; + + default: + if (lex->lookAhead(0) == '(' && lex->lookAhead(1) == ')') { + nextToken(); + nextToken(); + return true; + } else if (lex->lookAhead(0) == '[' && lex->lookAhead(1) == ']') { + nextToken(); + nextToken(); + return true; + } + } + + return false; +} + +bool Parser::parseCvQualify(GroupAST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseCvQualify()" << endl; + + int start = lex->index(); + + GroupAST::Node ast = CreateNode(); + + int n = 0; + while (!lex->lookAhead(0).isNull()) { + int tk = lex->lookAhead(0); + if (tk == Token_const || tk == Token_volatile) { + ++n; + int startWord = lex->index(); + nextToken(); + AST::Node word = CreateNode(); + UPDATE_POS(word, startWord, lex->index()); + ast->addNode(word); + } else + break; + } + + if (n == 0) + return false; + + + DEBUG("Parser") << "-----------------> token = " << lex->lookAhead(0).text() << endl; + UPDATE_POS(ast, start, lex->index()); + + node = ast; + return true; +} + +bool Parser::parseSimpleTypeSpecifier(TypeSpecifierAST::Node& node) +{ + int start = lex->index(); + bool isIntegral = false; + bool done = false; + + while (!done) { + + switch (lex->lookAhead(0)) { + case Token_char: + case Token_wchar_t: + case Token_bool: + case Token_short: + case Token_int: + case Token_long: + case Token_signed: + case Token_unsigned: + case Token_float: + case Token_double: + case Token_void: + isIntegral = true; + nextToken(); + break; + + default: + done = true; + } + } + + TypeSpecifierAST::Node ast = CreateNode(); + if (isIntegral) { + ClassOrNamespaceNameAST::Node cl = CreateNode(); + + AST::Node n = CreateNode(); + UPDATE_POS(n, start, lex->index()); + cl->setName(n); + UPDATE_POS(cl, start, lex->index()); + + NameAST::Node name = CreateNode(); + name->setUnqualifiedName(cl); + UPDATE_POS(name, start, lex->index()); + ast->setName(name); + + } else { + NameAST::Node name; + if (!parseName(name)) { + lex->setIndex(start); + return false; + } + ast->setName(name); + } + + UPDATE_POS(ast, start, lex->index()); + node = ast; + return true; +} + +bool Parser::parsePtrOperator(AST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parsePtrOperator()" << endl; + + int start = lex->index(); + + if (lex->lookAhead(0) == '&') { + nextToken(); + } else if (lex->lookAhead(0) == '*') { + nextToken(); + } else { + int index = lex->index(); + AST::Node memPtr; + if (!parsePtrToMember(memPtr)) { + lex->setIndex(index); + return false; + } + } + + GroupAST::Node cv; + parseCvQualify(cv); + + AST::Node ast = CreateNode(); + UPDATE_POS(ast, start, lex->index()); + node = ast; + + return true; +} + + +bool Parser::parseTemplateArgument(AST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseTemplateArgument()" << endl; + + int start = lex->index(); + if (parseTypeId(node)) { + if (lex->lookAhead(0) == ',' || lex->lookAhead(0) == '>') + return true; + } + + lex->setIndex(start); + if (!parseLogicalOrExpression(node, true)) { + return false; + } + + return true; +} + +bool Parser::parseTypeSpecifier(TypeSpecifierAST::Node& spec) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseTypeSpecifier()" << endl; + + GroupAST::Node cv; + parseCvQualify(cv); + + if (parseElaboratedTypeSpecifier(spec) || parseSimpleTypeSpecifier(spec)) { + spec->setCvQualify(cv); + + GroupAST::Node cv2; + parseCvQualify(cv2); + spec->setCv2Qualify(cv2); + + return true; + } + + return false; +} + +bool Parser::parseDeclarator(DeclaratorAST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseDeclarator()" << endl; + + int start = lex->index(); + + DeclaratorAST::Node ast = CreateNode(); + + DeclaratorAST::Node decl; + NameAST::Node declId; + + AST::Node ptrOp; + while (parsePtrOperator(ptrOp)) { + ast->addPtrOp(ptrOp); + } + + if (lex->lookAhead(0) == '(') { + nextToken(); + + if (!parseDeclarator(decl)) { + return false; + } + ast->setSubDeclarator(decl); + + if (lex->lookAhead(0) != ')') { + return false; + } + nextToken(); + } else { + + if (lex->lookAhead(0) == ':') { + // unnamed bitfield + } else if (parseDeclaratorId(declId)) { + ast->setDeclaratorId(declId); + } else { + lex->setIndex(start); + return false; + } + + if (lex->lookAhead(0) == ':') { + nextToken(); + AST::Node expr; + if (!parseConstantExpression(expr)) { + reportError(i18n("Constant expression expected")); + } + goto update_pos; + } + } + + { + bool isVector = true; + + while (lex->lookAhead(0) == '[') { + int startArray = lex->index(); + nextToken(); + AST::Node expr; + parseCommaExpression(expr); + + ADVANCE(']', "]"); + AST::Node array = CreateNode(); + UPDATE_POS(array, startArray, lex->index()); + ast->addArrayDimension(array); + isVector = true; + } + + bool skipParen = false; + if (lex->lookAhead(0) == Token_identifier && lex->lookAhead(1) == '(' && lex->lookAhead(2) == '(') { + nextToken(); + nextToken(); + skipParen = true; + } + + if (ast->subDeclarator() && (!isVector || lex->lookAhead(0) != '(')) { + lex->setIndex(start); + return false; + } + + int index = lex->index(); + if (lex->lookAhead(0) == '(') { + nextToken(); + + ParameterDeclarationClauseAST::Node params; + if (!parseParameterDeclarationClause(params)) { + DEBUG("Parser") << "----------------------> not a parameter declaration, maybe an initializer!?" << endl; + lex->setIndex(index); + goto update_pos; + } + ast->setParameterDeclarationClause(params); + + if (lex->lookAhead(0) != ')') { + lex->setIndex(index); + goto update_pos; + } + + nextToken(); // skip ')' + + int startConstant = lex->index(); + if (lex->lookAhead(0) == Token_const) { + nextToken(); + AST::Node constant = CreateNode(); + UPDATE_POS(constant, startConstant, lex->index()); + ast->setConstant(constant); + } + + GroupAST::Node except; + if (parseExceptionSpecification(except)) { + ast->setExceptionSpecification(except); + } + } + + if (skipParen) { + if (lex->lookAhead(0) != ')') { + reportError(i18n("')' expected")); + } else + nextToken(); + } + + } + +update_pos: + UPDATE_POS(ast, start, lex->index()); + node = ast; + + return true; +} + +bool Parser::parseAbstractDeclarator(DeclaratorAST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseDeclarator()" << endl; + int start = lex->index(); + + DeclaratorAST::Node ast = CreateNode(); + + DeclaratorAST::Node decl; + NameAST::Node declId; + + AST::Node ptrOp; + while (parsePtrOperator(ptrOp)) { + ast->addPtrOp(ptrOp); + } + + if (lex->lookAhead(0) == '(') { + nextToken(); + + if (!parseAbstractDeclarator(decl)) { + return false; + } + ast->setSubDeclarator(decl); + + if (lex->lookAhead(0) != ')') { + return false; + } + nextToken(); + } + + { + + while (lex->lookAhead(0) == '[') { + int startArray = lex->index(); + nextToken(); + AST::Node expr; + skipCommaExpression(expr); + + ADVANCE(']', "]"); + AST::Node array = CreateNode(); + UPDATE_POS(array, startArray, lex->index()); + ast->addArrayDimension(array); + } + + bool skipParen = false; + if (lex->lookAhead(0) == Token_identifier && lex->lookAhead(1) == '(' && lex->lookAhead(2) == '(') { + nextToken(); + nextToken(); + skipParen = true; + } + + int index = lex->index(); + if (lex->lookAhead(0) == '(') { + nextToken(); + + ParameterDeclarationClauseAST::Node params; + if (!parseParameterDeclarationClause(params)) { + lex->setIndex(index); + goto UPDATE_POS; + } + ast->setParameterDeclarationClause(params); + + if (lex->lookAhead(0) != ')') { + lex->setIndex(index); + goto UPDATE_POS; + } else + nextToken(); + + int startConstant = lex->index(); + if (lex->lookAhead(0) == Token_const) { + nextToken(); + AST::Node constant = CreateNode(); + UPDATE_POS(constant, startConstant, lex->index()); + ast->setConstant(constant); + } + + GroupAST::Node except; + if (parseExceptionSpecification(except)) { + ast->setExceptionSpecification(except); + } + } + + if (skipParen) { + if (lex->lookAhead(0) != ')') { + reportError(i18n("')' expected")); + } else + nextToken(); + } + + } + +UPDATE_POS: + UPDATE_POS(ast, start, lex->index()); + node = ast; + + return true; +} + + +bool Parser::parseEnumSpecifier(TypeSpecifierAST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseEnumSpecifier()" << endl; + + int start = lex->index(); + + if (lex->lookAhead(0) != Token_enum) { + return false; + } + + nextToken(); + + Comment c = comment(); + clearComment(); + NameAST::Node name; + parseName(name); + + if (lex->lookAhead(0) != '{') { + lex->setIndex(start); + return false; + } + nextToken(); + + EnumSpecifierAST::Node ast = CreateNode(); + ast->setName(name); + + ast->setComment(c); + + EnumeratorAST::Node enumerator; + if (parseEnumerator(enumerator)) { + ast->addEnumerator(enumerator); + + while (lex->lookAhead(0) == ',') { + nextToken(); + + if (!parseEnumerator(enumerator)) { + //reportError(i18n("Enumerator expected")); + break; + } + + ast->addEnumerator(enumerator); + } + } + + clearComment(); + + if (lex->lookAhead(0) != '}') + reportError(i18n("} missing")); + else + nextToken(); + + + UPDATE_POS(ast, start, lex->index()); + node = ast; + + return true; +} + +bool Parser::parseTemplateParameterList(TemplateParameterListAST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseTemplateParameterList()" << endl; + + int start = lex->index(); + + TemplateParameterListAST::Node ast = CreateNode(); + + TemplateParameterAST::Node param; + if (!parseTemplateParameter(param)) { + return false; + } + ast->addTemplateParameter(param); + + while (lex->lookAhead(0) == ',') { + nextToken(); + + if (!parseTemplateParameter(param)) { + syntaxError(); + break; + } else { + ast->addTemplateParameter(param); + } + } + + UPDATE_POS(ast, start, lex->index()); + node = ast; + + return true; +} + +bool Parser::parseTemplateParameter(TemplateParameterAST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseTemplateParameter()" << endl; + + int start = lex->index(); + TemplateParameterAST::Node ast = CreateNode(); + + TypeParameterAST::Node typeParameter; + ParameterDeclarationAST::Node param; + + int tk = lex->lookAhead(0); + + if ((tk == Token_class || tk == Token_typename || tk == Token_template) && parseTypeParameter(typeParameter)) { + ast->setTypeParameter(typeParameter); + goto ok; + } + + if (!parseParameterDeclaration(param)) + return false; + ast->setTypeValueParameter(param); + +ok: + UPDATE_POS(ast, start, lex->index()); + node = ast; + + return true; +} + +bool Parser::parseTypeParameter(TypeParameterAST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseTypeParameter()" << endl; + + int start = lex->index(); + TypeParameterAST::Node ast = CreateNode(); + + AST_FROM_TOKEN(kind, lex->index()); + ast->setKind(kind); + + switch (lex->lookAhead(0)) { + + case Token_class: + case Token_typename: { + nextToken(); // skip class + + // parse optional name + NameAST::Node name; + if (parseName(name)) { + ast->setName(name); + if (lex->lookAhead(0) == '=') { + nextToken(); + + AST::Node typeId; + if (!parseTypeId(typeId)) { + syntaxError(); + return false; + } + ast->setTypeId(typeId); + } + } + } + break; + + case Token_template: { + nextToken(); // skip template + ADVANCE('<', '<'); + + TemplateParameterListAST::Node params; + if (!parseTemplateParameterList(params)) { + return false; + } + ast->setTemplateParameterList(params); + + ADVANCE('>', ">"); + + if (lex->lookAhead(0) == Token_class) + nextToken(); + + // parse optional name + NameAST::Node name; + if (parseName(name)) { + ast->setName(name); + if (lex->lookAhead(0) == '=') { + nextToken(); + + AST::Node typeId; + if (!parseTypeId(typeId)) { + syntaxError(); + return false; + } + ast->setTypeId(typeId); + } + } + + if (lex->lookAhead(0) == '=') { + nextToken(); + + NameAST::Node templ_name; + parseName(templ_name); + } + } + break; + + default: + return false; + + } // end switch + + + UPDATE_POS(ast, start, lex->index()); + node = ast; + return true; +} + +bool Parser::parseStorageClassSpecifier(GroupAST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseStorageClassSpecifier()" << endl; + + int start = lex->index(); + GroupAST::Node ast = CreateNode(); + + while (!lex->lookAhead(0).isNull()) { + int tk = lex->lookAhead(0); + if (tk == Token_friend || tk == Token_auto || tk == Token_register || tk == Token_static || + tk == Token_extern || tk == Token_mutable) { + int startNode = lex->index(); + nextToken(); + + AST::Node n = CreateNode(); + UPDATE_POS(n, startNode, lex->index()); + ast->addNode(n); + } else + break; + } + + if (ast->nodeList().count() == 0) + return false; + + UPDATE_POS(ast, start, lex->index()); + node = ast; + return true; +} + +bool Parser::parseFunctionSpecifier(GroupAST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseFunctionSpecifier()" << endl; + + int start = lex->index(); + GroupAST::Node ast = CreateNode(); + + while (!lex->lookAhead(0).isNull()) { + int tk = lex->lookAhead(0); + if (tk == Token_inline || tk == Token_virtual || tk == Token_explicit) { + int startNode = lex->index(); + nextToken(); + + AST::Node n = CreateNode(); + UPDATE_POS(n, startNode, lex->index()); + ast->addNode(n); + } else { + break; + } + } + + if (ast->nodeList().count() == 0) + return false; + + UPDATE_POS(ast, start, lex->index()); + node = ast; + return true; +} + +bool Parser::parseTypeId(AST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseTypeId()" << endl; + + /// @todo implement the AST for typeId + int start = lex->index(); + AST::Node ast = CreateNode(); + + TypeSpecifierAST::Node spec; + if (!parseTypeSpecifier(spec)) { + return false; + } + + DeclaratorAST::Node decl; + parseAbstractDeclarator(decl); + + UPDATE_POS(ast, start, lex->index()); + node = ast; + + return true; +} + +bool Parser::parseInitDeclaratorList(InitDeclaratorListAST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseInitDeclaratorList()" << endl; + + int start = lex->index(); + + InitDeclaratorListAST::Node ast = CreateNode(); + InitDeclaratorAST::Node decl; + + if (!parseInitDeclarator(decl)) { + return false; + } + ast->addInitDeclarator(decl); + + while (lex->lookAhead(0) == ',') { + nextToken(); + + if (!parseInitDeclarator(decl)) { + syntaxError(); + break; + } + ast->addInitDeclarator(decl); + } + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseInitDeclaratorList() -- end" << endl; + + UPDATE_POS(ast, start, lex->index()); + node = ast; + + return true; +} + +bool Parser::parseParameterDeclarationClause(ParameterDeclarationClauseAST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseParameterDeclarationClause()" << endl; + + int start = lex->index(); + + ParameterDeclarationClauseAST::Node ast = CreateNode(); + + ParameterDeclarationListAST::Node params; + if (!parseParameterDeclarationList(params)) { + + if (lex->lookAhead(0) == ')') + goto good; + + if (lex->lookAhead(0) == Token_ellipsis && lex->lookAhead(1) == ')') { + AST_FROM_TOKEN(ellipsis, lex->index()); + ast->setEllipsis(ellipsis); + nextToken(); + goto good; + } + return false; + } + + if (lex->lookAhead(0) == Token_ellipsis) { + AST_FROM_TOKEN(ellipsis, lex->index()); + ast->setEllipsis(ellipsis); + nextToken(); + } + +good: + ast->setParameterDeclarationList(params); + + /// @todo add ellipsis + UPDATE_POS(ast, start, lex->index()); + node = ast; + + return true; +} + + +void Parser::nextToken(bool skipComm) +{ + lex->nextToken(); + if (skipComm) { + if (lex->lookAhead(0) == Token_comment) { + processComment(); + nextToken(); + } + } +} + + +Comment Parser::comment() +{ + return m_commentStore.latestComment(); +} + + +void Parser::preparseLineComments(int l) +{ + for (int a = 0; a < 40; a++) { + if (lex->lookAhead(a).isNull()) break; + int line, col; + lex->lookAhead(a).getStartPosition(&line, &col); + if (line < l) { + continue; + } else if (line == l) { + if (lex->lookAhead(a) == Token_comment) { + processComment(a); + } + } else { + break; + } + } +} + + +void Parser::processComment(int offset) +{ + int line, col; + lex->lookAhead(offset).getStartPosition(&line, &col); + m_commentStore.addComment(Comment(lex->lookAhead(offset).text(), line)); +} + +template +void Parser::eventuallyTakeComment(int startLn, int endLn, Type& ast) +{ + if (comment().line() >= startLn && comment().line() <= endLn) { + if (&(*ast)) { + if (comment()) { + ast->setComment(comment()); + } + } + + clearComment(); + } +} + +template +void Parser::eventuallyTakeComment(Type& ast) +{ + if (&(*ast) && comment()) { + ast->setComment(comment()); + } + + clearComment(); +} + +void Parser::clearComment() +{ + + m_commentStore.clear(); + +} + +int Parser::currentLine() +{ + int ln, col; + lex->lookAhead(0).getStartPosition(&ln, &col); + return ln; +} + +bool Parser::parseParameterDeclarationList(ParameterDeclarationListAST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseParameterDeclarationList()" << endl; + + int start = lex->index(); + + ParameterDeclarationListAST::Node ast = CreateNode(); + + ParameterDeclarationAST::Node param; + if (!parseParameterDeclaration(param)) { + lex->setIndex(start); + return false; + } + ast->addParameter(param); + + while (lex->lookAhead(0) == ',') { + nextToken(); + + if (lex->lookAhead(0) == Token_ellipsis) + break; + + if (!parseParameterDeclaration(param)) { + lex->setIndex(start); + return false; + } + ast->addParameter(param); + } + + UPDATE_POS(ast, start, lex->index()); + node = ast; + + return true; +} + +bool Parser::parseParameterDeclaration(ParameterDeclarationAST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseParameterDeclaration()" << endl; + + int start = lex->index(); + + // parse decl spec + TypeSpecifierAST::Node spec; + if (!parseTypeSpecifier(spec)) { + lex->setIndex(start); + return false; + } + + int index = lex->index(); + + DeclaratorAST::Node decl; + if (!parseDeclarator(decl)) { + lex->setIndex(index); + + // try with abstract declarator + if (!parseAbstractDeclarator(decl)) + return false; + } + + AST::Node expr; + if (lex->lookAhead(0) == '=') { + nextToken(); + if (!parseLogicalOrExpression(expr,true)) { + //reportError(i18n("Expression expected")); + } + } + + ParameterDeclarationAST::Node ast = CreateNode(); + ast->setTypeSpec(spec); + ast->setDeclarator(decl); + ast->setExpression(expr); + + UPDATE_POS(ast, start, lex->index()); + node = ast; + + return true; +} + + +bool Parser::parseClassSpecifier(TypeSpecifierAST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseClassSpecifier()" << endl; + + int start = lex->index(); + + AST::Node classKey; + int classKeyStart = lex->index(); + + int kind = lex->lookAhead(0); + if (kind == Token_class || kind == Token_struct || kind == Token_union) { + AST::Node asn = CreateNode(); + classKey = asn; + nextToken(); + UPDATE_POS(classKey, classKeyStart, lex->index()); + } else { + return false; + } + + GroupAST::Node winDeclSpec; + parseWinDeclSpec(winDeclSpec); + + while (lex->lookAhead(0) == Token_identifier && lex->lookAhead(1) == Token_identifier) + nextToken(); + + NameAST::Node name; + parseName(name); + + BaseClauseAST::Node bases; + if (lex->lookAhead(0) == ':') { + if (!parseBaseClause(bases)) { + skipUntil('{'); + } + } + + if (lex->lookAhead(0) != '{') { + lex->setIndex(start); + return false; + } + + ClassSpecifierAST::Node ast = CreateNode(); + + eventuallyTakeComment(ast); + + ADVANCE('{', '{'); + + + ast->setWinDeclSpec(winDeclSpec); + ast->setClassKey(classKey); + ast->setName(name); + ast->setBaseClause(bases); + + + while (!lex->lookAhead(0).isNull()) { + if (lex->lookAhead(0) == '}') + break; + + DeclarationAST::Node memSpec; + int startDecl = lex->index(); + if (!parseMemberSpecification(memSpec)) { + if (startDecl == lex->index()) + nextToken(); // skip at least one token + skipUntilDeclaration(); + } else + ast->addDeclaration(memSpec); + } + + clearComment(); + + if (lex->lookAhead(0) != '}') { + reportError(i18n("} missing")); + } else + nextToken(); + + UPDATE_POS(ast, start, lex->index()); + node = ast; + + return true; +} + +bool Parser::parseAccessSpecifier(AST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseAccessSpecifier()" << endl; + + int start = lex->index(); + + switch (lex->lookAhead(0)) { + case Token_public: + case Token_protected: + case Token_private: { + AST::Node asn = CreateNode(); + node = asn; + nextToken(); + UPDATE_POS(node, start, lex->index()); + return true; + } + } + + return false; +} + +bool Parser::parseMemberSpecification(DeclarationAST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseMemberSpecification()" << endl; + + int start = lex->index(); + + AST::Node access; + + if (lex->lookAhead(0) == ';') { + nextToken(); + return true; + } else if (lex->lookAhead(0) == Token_Q_OBJECT || lex->lookAhead(0) == Token_K_DCOP) { + nextToken(); + return true; + } else if (lex->lookAhead(0) == Token_signals || lex->lookAhead(0) == Token_k_dcop || lex->lookAhead(0) == Token_k_dcop_signals) { + AccessDeclarationAST::Node ast = CreateNode(); + nextToken(); + AST::Node n = CreateNode(); + UPDATE_POS(n, start, lex->index()); + ast->addAccess(n); + ADVANCE(':', ":"); + UPDATE_POS(ast, start, lex->index()); + node = ast; + return true; + } else if (parseTypedef(node)) { + return true; + } else if (parseUsing(node)) { + return true; + } else if (parseTemplateDeclaration(node)) { + return true; + } else if (parseAccessSpecifier(access)) { + AccessDeclarationAST::Node ast = CreateNode(); + ast->addAccess(access); + + int startSlot = lex->index(); + if (lex->lookAhead(0) == Token_slots) { + nextToken(); + AST::Node sl = CreateNode(); + UPDATE_POS(sl, startSlot, lex->index()); + ast->addAccess(sl); + } + ADVANCE(':', ":"); + UPDATE_POS(ast, start, lex->index()); + node = ast; + return true; + } + + lex->setIndex(start); + + GroupAST::Node storageSpec; + parseStorageClassSpecifier(storageSpec); + + GroupAST::Node cv; + parseCvQualify(cv); + + TypeSpecifierAST::Node spec; + if (parseEnumSpecifier(spec) || parseClassSpecifier(spec)) { + spec->setCvQualify(cv); + + GroupAST::Node cv2; + parseCvQualify(cv2); + spec->setCv2Qualify(cv2); + + InitDeclaratorListAST::Node declarators; + parseInitDeclaratorList(declarators); + ADVANCE(';', ";"); + + SimpleDeclarationAST::Node ast = CreateNode(); + ast->setTypeSpec(spec); + ast->setInitDeclaratorList(declarators); + UPDATE_POS(ast, start, lex->index()); + node = ast; + + return true; + } + + lex->setIndex(start); + return parseDeclarationInternal(node); +} + +bool Parser::parseCtorInitializer(AST::Node& /*node*/) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseCtorInitializer()" << endl; + + if (lex->lookAhead(0) != ':') { + return false; + } + nextToken(); + + AST::Node inits; + if (!parseMemInitializerList(inits)) { + reportError(i18n("Member initializers expected")); + } + + return true; +} + +bool Parser::parseElaboratedTypeSpecifier(TypeSpecifierAST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseElaboratedTypeSpecifier()" << endl; + + int start = lex->index(); + + int tk = lex->lookAhead(0); + if (tk == Token_class || + tk == Token_struct || + tk == Token_union || + tk == Token_enum || + tk == Token_typename) { + AST::Node kind = CreateNode(); + nextToken(); + UPDATE_POS(kind, start, lex->index()); + + NameAST::Node name; + + if (parseName(name)) { + ElaboratedTypeSpecifierAST::Node ast = CreateNode(); + ast->setKind(kind); + ast->setName(name); + UPDATE_POS(ast, start, lex->index()); + node = ast; + + return true; + } + } + + lex->setIndex(start); + return false; +} + +bool Parser::parseDeclaratorId(NameAST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseDeclaratorId()" << endl; + return parseName(node); +} + +bool Parser::parseExceptionSpecification(GroupAST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseExceptionSpecification()" << endl; + + if (lex->lookAhead(0) != Token_throw) { + return false; + } + nextToken(); + + ADVANCE('(', "("); + if (lex->lookAhead(0) == Token_ellipsis) { + // extension found in MSVC++ 7.x headers + int start = lex->index(); + GroupAST::Node ast = CreateNode(); + AST_FROM_TOKEN(ellipsis, lex->index()); + ast->addNode(ellipsis); + nextToken(); + UPDATE_POS(ast, start, lex->index()); + node = ast; + } else if (lex->lookAhead(0) == ')') { + node = CreateNode(); + } else { + parseTypeIdList(node); + } + ADVANCE(')', ")"); + + return true; +} + +bool Parser::parseEnumerator(EnumeratorAST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseEnumerator()" << endl; + + int start = lex->index(); + + if (lex->lookAhead(0) != Token_identifier) { + return false; + } + + nextToken(); + + + EnumeratorAST::Node ena = CreateNode(); + node = ena; + + AST::Node id = CreateNode(); + UPDATE_POS(id, start, lex->index()); + node->setId(id); + int line = currentLine(); + + if (lex->lookAhead(0) == '=') { + nextToken(); + + AST::Node expr; + line = currentLine(); + if (!parseConstantExpression(expr)) { + reportError(i18n("Constant expression expected")); + } + node->setExpr(expr); + } + + UPDATE_POS(node, start, lex->index()); + + preparseLineComments(line); + + node->setComment(m_commentStore.getCommentInRange(line)); + + return true; +} + +bool Parser::parseInitDeclarator(InitDeclaratorAST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseInitDeclarator()" << endl; + + int start = lex->index(); + + DeclaratorAST::Node decl; + AST::Node init; + if (!parseDeclarator(decl)) { + return false; + } + + parseInitializer(init); + + InitDeclaratorAST::Node ast = CreateNode(); + ast->setDeclarator(decl); + ast->setInitializer(init); + UPDATE_POS(ast, start, lex->index()); + node = ast; + + return true; +} + + + +bool Parser::parseBaseClause(BaseClauseAST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseBaseClause()" << endl; + + int start = lex->index(); + if (lex->lookAhead(0) != ':') { + return false; + } + nextToken(); + + BaseClauseAST::Node bca = CreateNode(); + + BaseSpecifierAST::Node baseSpec; + if (parseBaseSpecifier(baseSpec)) { + bca->addBaseSpecifier(baseSpec); + + while (lex->lookAhead(0) == ',') { + nextToken(); + + if (!parseBaseSpecifier(baseSpec)) { + reportError(i18n("Base class specifier expected")); + return false; + } + bca->addBaseSpecifier(baseSpec); + } + } else + return false; + + UPDATE_POS(bca, start, lex->index()); + node = bca; + + return true; +} + +bool Parser::parseInitializer(AST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseInitializer()" << endl; + + if (lex->lookAhead(0) == '=') { + nextToken(); + + AST::Node init; + if (!parseInitializerClause(node)) { + reportError(i18n("Initializer clause expected")); + return false; + } + } else if (lex->lookAhead(0) == '(') { + nextToken(); + AST::Node expr; + skipCommaExpression(expr); + + ADVANCE(')', ")"); + } + + return false; +} + +bool Parser::parseMemInitializerList(AST::Node& /*node*/) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseMemInitializerList()" << endl; + + AST::Node init; + if (!parseMemInitializer(init)) { + return false; + } + + while (lex->lookAhead(0) == ',') { + nextToken(); + + if (parseMemInitializer(init)) { + } else { + break; + } + } + + return true; +} + +bool Parser::parseMemInitializer(AST::Node& /*node*/) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseMemInitializer()" << endl; + + NameAST::Node initId; + if (!parseMemInitializerId(initId)) { + reportError(i18n("Identifier expected")); + return false; + } + ADVANCE('(', '('); + AST::Node expr; + skipCommaExpression(expr); + ADVANCE(')', ')'); + + return true; +} + +bool Parser::parseTypeIdList(GroupAST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseTypeIdList()" << endl; + + int start = lex->index(); + + AST::Node typeId; + if (!parseTypeId(typeId)) { + return false; + } + + GroupAST::Node ast = CreateNode(); + ast->addNode(typeId); + + while (lex->lookAhead(0) == ',') { + nextToken(); + if (parseTypeId(typeId)) { + ast->addNode(typeId); + } else { + reportError(i18n("Type id expected")); + break; + } + } + + UPDATE_POS(ast, start, lex->index()); + node = ast; + return true; +} + +bool Parser::parseBaseSpecifier(BaseSpecifierAST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseBaseSpecifier()" << endl; + + int start = lex->index(); + BaseSpecifierAST::Node ast = CreateNode(); + + AST::Node access; + if (lex->lookAhead(0) == Token_virtual) { + AST_FROM_TOKEN(virt, lex->index()); + ast->setIsVirtual(virt); + + nextToken(); + + parseAccessSpecifier(access); + } else { + parseAccessSpecifier(access); + + if (lex->lookAhead(0) == Token_virtual) { + AST_FROM_TOKEN(virt, lex->index()); + ast->setIsVirtual(virt); + nextToken(); + } + } + + NameAST::Node name; + if (!parseName(name)) { + reportError(i18n("Class name expected")); + } + + ast->setAccess(access); + ast->setName(name); + UPDATE_POS(ast, start, lex->index()); + node = ast; + + return true; +} + + +bool Parser::parseInitializerClause(AST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseInitializerClause()" << endl; + + if (lex->lookAhead(0) == '{') { + if (!skip('{','}')) { + reportError(i18n("} missing")); + } else { + clearComment(); + nextToken(); + } + } else { + if (!parseAssignmentExpression(node)) { + //reportError(i18n("Expression expected")); + } + } + + return true; +} + +bool Parser::parseMemInitializerId(NameAST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseMemInitializerId()" << endl; + + return parseName(node); +} + +bool Parser::parsePtrToMember(AST::Node& /*node*/) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parsePtrToMember()" << endl; + + if (lex->lookAhead(0) == Token_scope) { + nextToken(); + } + + while (lex->lookAhead(0) == Token_identifier) { + nextToken(); + + if (lex->lookAhead(0) == Token_scope && lex->lookAhead(1) == '*') { + nextToken(); // skip :: + nextToken(); // skip * + return true; + } else + break; + } + + return false; +} + +bool Parser::parseUnqualifiedName(ClassOrNamespaceNameAST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseUnqualifiedName()" << endl; + + int start = lex->index(); + bool isDestructor = false; + + ClassOrNamespaceNameAST::Node ast = CreateNode(); + + if (lex->lookAhead(0) == Token_identifier) { + int startName = lex->index(); + AST::Node n = CreateNode(); + nextToken(); + UPDATE_POS(n, startName, lex->index()); + ast->setName(n); + } else if (lex->lookAhead(0) == '~' && lex->lookAhead(1) == Token_identifier) { + int startName = lex->index(); + AST::Node n = CreateNode(); + nextToken(); // skip ~ + nextToken(); // skip classname + UPDATE_POS(n, startName, lex->index()); + ast->setName(n); + isDestructor = true; + } else if (lex->lookAhead(0) == Token_operator) { + AST::Node n; + if (!parseOperatorFunctionId(n)) + return false; + ast->setName(n); + } else { + return false; + } + + if (!isDestructor) { + + int index = lex->index(); + + if (lex->lookAhead(0) == '<') { + nextToken(); + + // optional template arguments + TemplateArgumentListAST::Node args; + parseTemplateArgumentList(args); + + if (lex->lookAhead(0) != '>') { + lex->setIndex(index); + } else { + nextToken(); + ast->setTemplateArgumentList(args); + } + } + } + + UPDATE_POS(ast, start, lex->index()); + node = ast; + + return true; +} + +bool Parser::parseStringLiteral(AST::Node& /*node*/) +{ + while (!lex->lookAhead(0).isNull()) { + if (lex->lookAhead(0) == Token_identifier && + lex->lookAhead(0).text() == "L" && lex->lookAhead(1) == Token_string_literal) { + + nextToken(); + nextToken(); + } else if (lex->lookAhead(0) == Token_string_literal) { + nextToken(); + } else + return false; + } + return true; +} + +bool Parser::skipExpressionStatement(StatementAST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::skipExpressionStatement()" << endl; + + int start = lex->index(); + + AST::Node expr; + skipCommaExpression(expr); + + ADVANCE(';', ";"); + + ExpressionStatementAST::Node ast = CreateNode(); + ast->setExpression(expr); + UPDATE_POS(ast, start, lex->index()); + node = ast; + + return true; +} + +bool Parser::parseStatement(StatementAST::Node& node) // thanks to fiore@8080.it ;) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseStatement()" << endl; + switch (lex->lookAhead(0)) { + + case Token_while: + return parseWhileStatement(node); + + case Token_do: + return parseDoStatement(node); + + case Token_for: + return parseForStatement(node); + + case Token_foreach: + return parseForEachStatement(node); + + case Token_if: + return parseIfStatement(node); + + case Token_switch: + return parseSwitchStatement(node); + + case Token_try: + return parseTryBlockStatement(node); + + case Token_case: + case Token_default: + return parseLabeledStatement(node); + + case Token_break: + case Token_continue: + nextToken(); + ADVANCE(';', ";"); + return true; + + case Token_goto: + nextToken(); + ADVANCE(Token_identifier, "identifier"); + ADVANCE(';', ";"); + return true; + + case Token_return: { + nextToken(); + AST::Node expr; + skipCommaExpression(expr); + ADVANCE(';', ";"); + } + return true; + + case '{': + return parseCompoundStatement(node); + + case Token_identifier: + if (parseLabeledStatement(node)) + return true; + break; + } + + DEBUG("Parser") << "------------> try with declaration statement" << endl; + if (parseDeclarationStatement(node)) + return true; + + return skipExpressionStatement(node); +} + +bool Parser::parseCondition(ConditionAST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseCondition()" << endl; + + int start = lex->index(); + + ConditionAST::Node ast = CreateNode(); + + TypeSpecifierAST::Node spec; + if (parseTypeSpecifier(spec)) { + DeclaratorAST::Node decl; + if (parseDeclarator(decl)) { + if (lex->lookAhead(0) == '=') { + nextToken(); + + AST::Node expr; + if (skipExpression(expr)) { + ast->setTypeSpec(spec); + ast->setDeclarator(decl); + ast->setExpression(expr); + + UPDATE_POS(ast, start, lex->index()); + node = ast; + + return true; + } + } else { + ast->setTypeSpec(spec); + ast->setDeclarator(decl); + + UPDATE_POS(ast, start, lex->index()); + node = ast; + + return true; + } + } + } + + lex->setIndex(start); + + AST::Node expr; + if (!skipCommaExpression(expr)) + return false; + + ast->setExpression(expr); + UPDATE_POS(ast, start, lex->index()); + node = ast; + return true; +} + + +bool Parser::parseWhileStatement(StatementAST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseWhileStatement()" << endl; + int start = lex->index(); + + ADVANCE(Token_while, "while"); + ADVANCE('(' , "("); + + ConditionAST::Node cond; + if (!parseCondition(cond)) { + reportError(i18n("condition expected")); + return false; + } + ADVANCE(')', ")"); + + StatementAST::Node body; + if (!parseStatement(body)) { + reportError(i18n("statement expected")); + } + + WhileStatementAST::Node ast = CreateNode(); + ast->setCondition(cond); + ast->setStatement(body); + UPDATE_POS(ast, start, lex->index()); + node = ast; + + return true; +} + +bool Parser::parseDoStatement(StatementAST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseDoStatement()" << endl; + int start = lex->index(); + + ADVANCE(Token_do, "do"); + + StatementAST::Node body; + if (!parseStatement(body)) { + reportError(i18n("statement expected")); + //return false; + } + + ADVANCE_NR(Token_while, "while"); + ADVANCE_NR('(' , "("); + + AST::Node expr; + if (!skipCommaExpression(expr)) { + reportError(i18n("expression expected")); + //return false; + } + + ADVANCE_NR(')', ")"); + ADVANCE_NR(';', ";"); + + DoStatementAST::Node ast = CreateNode(); + ast->setStatement(body); + //ast->setCondition(condition); + UPDATE_POS(ast, start, lex->index()); + node = ast; + + return true; +} + +bool Parser::parseForStatement(StatementAST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseForStatement()" << endl; + int start = lex->index(); + + ADVANCE(Token_for, "for"); + ADVANCE('(', "("); + + StatementAST::Node init; + if (!parseForInitStatement(init)) { + reportError(i18n("for initialization expected")); + return false; + } + + ConditionAST::Node cond; + parseCondition(cond); + ADVANCE(';', ";"); + + AST::Node expr; + skipCommaExpression(expr); + ADVANCE(')', ")"); + + StatementAST::Node body; + parseStatement(body); + + ForStatementAST::Node ast = CreateNode(); + ast->setInitStatement(init); + ast->setCondition(cond); + // ast->setExpression(expression); + ast->setStatement(body); + UPDATE_POS(ast, start, lex->index()); + node = ast; + + return true; +} + +// qt4 [erbsland] +///@todo add the right parsing for the foreach statement +bool Parser::parseForEachStatement(StatementAST::Node& node) +{ + int start = lex->index(); + + ADVANCE(Token_foreach, "foreach"); + ADVANCE('(', "("); + + AST::Node expr; + // replace with the right parsing + skipCommaExpression(expr); + ADVANCE(')', ")"); + + StatementAST::Node body; + parseStatement(body); + + ForEachStatementAST::Node ast = CreateNode(); + // add here the parser results + ast->setStatement(body); + UPDATE_POS(ast, start, lex->index()); + node = ast; + + return true; +} + +bool Parser::parseForInitStatement(StatementAST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseForInitStatement()" << endl; + + if (parseDeclarationStatement(node)) + return true; + + return skipExpressionStatement(node); +} + +bool Parser::parseCompoundStatement(StatementAST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseCompoundStatement()" << endl; + int start = lex->index(); + + if (lex->lookAhead(0) != '{') { + return false; + } + nextToken(); + + StatementListAST::Node ast = CreateNode(); + + while (!lex->lookAhead(0).isNull()) { + if (lex->lookAhead(0) == '}') + break; + + StatementAST::Node stmt; + int startStmt = lex->index(); + if (!parseStatement(stmt)) { + if (startStmt == lex->index()) + nextToken(); + skipUntilStatement(); + } else { + ast->addStatement(stmt); + } + } + + clearComment(); + + if (lex->lookAhead(0) != '}') { + reportError(i18n("} expected")); + } else { + nextToken(); + } + + UPDATE_POS(ast, start, lex->index()); + node = ast; + + return true; +} + +bool Parser::parseIfStatement(StatementAST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseIfStatement()" << endl; + + int start = lex->index(); + + ADVANCE(Token_if, "if"); + + ADVANCE('(' , "("); + + IfStatementAST::Node ast = CreateNode(); + + ConditionAST::Node cond; + if (!parseCondition(cond)) { + reportError(i18n("condition expected")); + return false; + } + ADVANCE(')', ")"); + + StatementAST::Node stmt; + if (!parseStatement(stmt)) { + reportError(i18n("statement expected")); + } + + ast->setCondition(cond); + ast->setStatement(stmt); + + if (lex->lookAhead(0) == Token_else) { + nextToken(); + StatementAST::Node elseStmt; + if (!parseStatement(elseStmt)) { + reportError(i18n("statement expected")); + } + ast->setElseStatement(elseStmt); + } + + UPDATE_POS(ast, start, lex->index()); + node = ast; + + return true; +} + +bool Parser::parseSwitchStatement(StatementAST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseSwitchStatement()" << endl; + int start = lex->index(); + ADVANCE(Token_switch, "switch"); + + ADVANCE('(' , "("); + + ConditionAST::Node cond; + if (!parseCondition(cond)) { + reportError(i18n("condition expected")); + return false; + } + ADVANCE(')', ")"); + + StatementAST::Node stmt; + if (!parseCompoundStatement(stmt)) { + syntaxError(); + return false; + } + + SwitchStatementAST::Node ast = CreateNode(); + ast->setCondition(cond); + ast->setStatement(stmt); + UPDATE_POS(ast, start, lex->index()); + node = ast; + + return true; +} + +bool Parser::parseLabeledStatement(StatementAST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseLabeledStatement()" << endl; + switch (lex->lookAhead(0)) { + case Token_identifier: + case Token_default: + if (lex->lookAhead(1) == ':') { + nextToken(); + nextToken(); + + StatementAST::Node stmt; + if (parseStatement(stmt)) { + node = stmt; + return true; + } + } + break; + + case Token_case: { + nextToken(); + AST::Node expr; + if (!parseConstantExpression(expr)) { + reportError(i18n("expression expected")); + } else if (lex->lookAhead(0) == Token_ellipsis) { + nextToken(); + + AST::Node expr2; + if (!parseConstantExpression(expr2)) { + reportError(i18n("expression expected")); + } + } + ADVANCE(':', ":"); + + StatementAST::Node stmt; + if (parseStatement(stmt)) { + node = stmt; + return true; + } + } + break; + + } + + return false; +} + +bool Parser::parseBlockDeclaration(DeclarationAST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseBlockDeclaration()" << endl; + switch (lex->lookAhead(0)) { + case Token_typedef: + return parseTypedef(node); + case Token_using: + return parseUsing(node); + case Token_asm: + return parseAsmDefinition(node); + case Token_namespace: + return parseNamespaceAliasDefinition(node); + } + + int start = lex->index(); + + GroupAST::Node storageSpec; + parseStorageClassSpecifier(storageSpec); + + GroupAST::Node cv; + parseCvQualify(cv); + + TypeSpecifierAST::Node spec; + if (!parseTypeSpecifierOrClassSpec(spec)) { // replace with simpleTypeSpecifier?!?! + lex->setIndex(start); + return false; + } + spec->setCvQualify(cv); + + GroupAST::Node cv2; + parseCvQualify(cv2); + spec->setCv2Qualify(cv2); + + InitDeclaratorListAST::Node declarators; + parseInitDeclaratorList(declarators); + + if (lex->lookAhead(0) != ';') { + lex->setIndex(start); + return false; + } + nextToken(); + + SimpleDeclarationAST::Node ast = CreateNode(); + ast->setTypeSpec(spec); + ast->setInitDeclaratorList(declarators); + UPDATE_POS(ast, start, lex->index()); + node = ast; + + return true; +} + +bool Parser::parseNamespaceAliasDefinition(DeclarationAST::Node& /*node*/) +{ + if (lex->lookAhead(0) != Token_namespace) { + return false; + } + nextToken(); + + ADVANCE(Token_identifier, "identifier"); + ADVANCE('=', "="); + + NameAST::Node name; + if (!parseName(name)) { + reportError(i18n("Namespace name expected")); + } + + ADVANCE(';', ";"); + + return true; + +} + +bool Parser::parseDeclarationStatement(StatementAST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseDeclarationStatement()" << endl; + + int start = lex->index(); + + DeclarationAST::Node decl; + if (!parseBlockDeclaration(decl)) { + return false; + } + + DeclarationStatementAST::Node ast = CreateNode(); + ast->setDeclaration(decl); + UPDATE_POS(ast, start, lex->index()); + node = ast; + + DEBUG("Parser") << "---------------------> found a block declaration" << endl; + return true; +} + +bool Parser::parseDeclarationInternal(DeclarationAST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseDeclarationInternal()" << endl; + + int start = lex->index(); + + // that is for the case '__declspec(dllexport) int ...' or + // '__declspec(dllexport) inline int ...', etc. + GroupAST::Node winDeclSpec; + parseWinDeclSpec(winDeclSpec); + + GroupAST::Node funSpec; + bool hasFunSpec = parseFunctionSpecifier(funSpec); + + GroupAST::Node storageSpec; + bool hasStorageSpec = parseStorageClassSpecifier(storageSpec); + + if (hasStorageSpec && !hasFunSpec) + hasFunSpec = parseFunctionSpecifier(funSpec); + + // that is for the case 'friend __declspec(dllexport) ....' + GroupAST::Node winDeclSpec2; + parseWinDeclSpec(winDeclSpec2); + + GroupAST::Node cv; + parseCvQualify(cv); + + int index = lex->index(); + NameAST::Node name; + if (parseName(name) && lex->lookAhead(0) == '(') { + // no type specifier, maybe a constructor or a cast operator?? + + lex->setIndex(index); + + InitDeclaratorAST::Node declarator; + if (parseInitDeclarator(declarator)) { + int endSignature = lex->index(); + + switch (lex->lookAhead(0)) { + case ';': { + nextToken(); + + InitDeclaratorListAST::Node declarators = CreateNode(); + + // update declarators position + int startLine, startColumn, endLine, endColumn; + if (declarator.get()) { + declarator->getStartPosition(&startLine, &startColumn); + declarator->getEndPosition(&endLine, &endColumn); + declarators->setStartPosition(startLine, startColumn); + declarators->setEndPosition(endLine, endColumn); + } + declarators->addInitDeclarator(declarator); + + SimpleDeclarationAST::Node ast = CreateNode(); + ast->setInitDeclaratorList(declarators); + ast->setText(toString(start, endSignature)); + node = ast; + UPDATE_POS(node, start, lex->index()); + return true; + + } + break; + + case ':': { + AST::Node ctorInit; + StatementListAST::Node funBody; + if (parseCtorInitializer(ctorInit) && parseFunctionBody(funBody)) { + FunctionDefinitionAST::Node ast = CreateNode(); + ast->setStorageSpecifier(storageSpec); + ast->setFunctionSpecifier(funSpec); + ast->setInitDeclarator(declarator); + ast->setFunctionBody(funBody); + ast->setText(toString(start, endSignature)); + node = ast; + UPDATE_POS(node, start, lex->index()); + return true; + } + } + break; + + case '{': { + StatementListAST::Node funBody; + if (parseFunctionBody(funBody)) { + FunctionDefinitionAST::Node ast = CreateNode(); + ast->setStorageSpecifier(storageSpec); + ast->setFunctionSpecifier(funSpec); + ast->setInitDeclarator(declarator); + ast->setText(toString(start, endSignature)); + ast->setFunctionBody(funBody); + node = ast; + UPDATE_POS(node, start, lex->index()); + return true; + } + } + break; + + case '(': + case '[': + // ops!! it seems a declarator + goto start_decl; + break; + } + + } + + syntaxError(); + return false; + } + +start_decl: + lex->setIndex(index); + + if (lex->lookAhead(0) == Token_const && lex->lookAhead(1) == Token_identifier && lex->lookAhead(2) == '=') { + // constant definition + nextToken(); + InitDeclaratorListAST::Node declarators; + if (parseInitDeclaratorList(declarators)) { + ADVANCE(';', ";"); + DeclarationAST::Node ast = CreateNode(); + node = ast; + UPDATE_POS(node, start, lex->index()); + return true; + } + syntaxError(); + return false; + } + + Comment mcomment = comment(); + clearComment(); + + TypeSpecifierAST::Node spec; + if (parseTypeSpecifier(spec)) { + if (!hasFunSpec) + parseFunctionSpecifier(funSpec); // e.g. "void inline" + spec->setCvQualify(cv); + + InitDeclaratorListAST::Node declarators; + + InitDeclaratorAST::Node decl; + int startDeclarator = lex->index(); + bool maybeFunctionDefinition = false; + + if (lex->lookAhead(0) != ';') { + if (parseInitDeclarator(decl) && lex->lookAhead(0) == '{') { + // function definition + maybeFunctionDefinition = true; + } else { + lex->setIndex(startDeclarator); + if (!parseInitDeclaratorList(declarators)) { + syntaxError(); + return false; + } + } + } + + int endSignature = lex->index(); + switch (lex->lookAhead(0)) { + case ';': { + nextToken(); + SimpleDeclarationAST::Node ast = CreateNode(); + int line, col; + ast->setComment(mcomment); + if (&(*decl)) { + decl->getEndPosition(&line, &col); + + preparseLineComments(line); + Comment c = m_commentStore.getCommentInRange(line); + if (c) { + ast->addComment(c); + } + } + + ast->setStorageSpecifier(storageSpec); + ast->setFunctionSpecifier(funSpec); + ast->setText(toString(start, endSignature)); + ast->setTypeSpec(spec); + ast->setWinDeclSpec(winDeclSpec); + ast->setInitDeclaratorList(declarators); + + node = ast; + UPDATE_POS(node, start, lex->index()); + } + return true; + + case '{': { + if (!maybeFunctionDefinition) { + syntaxError(); + return false; + } + StatementListAST::Node funBody; + if (parseFunctionBody(funBody)) { + FunctionDefinitionAST::Node ast = CreateNode(); + + ast->setComment(mcomment); + + ast->setWinDeclSpec(winDeclSpec); + ast->setStorageSpecifier(storageSpec); + ast->setFunctionSpecifier(funSpec); + ast->setText(toString(start, endSignature)); + ast->setTypeSpec(spec); + ast->setFunctionBody(funBody); + ast->setInitDeclarator(decl); + node = ast; + UPDATE_POS(node, start, lex->index()); + return true; + } + } + break; + + } + } + + syntaxError(); + return false; +} + +bool Parser::parseFunctionBody(StatementListAST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseFunctionBody()" << endl; + + int start = lex->index(); + if (lex->lookAhead(0) != '{') { + return false; + } + nextToken(); + + StatementListAST::Node ast = CreateNode(); + + while (!lex->lookAhead(0).isNull()) { + if (lex->lookAhead(0) == '}') + break; + + StatementAST::Node stmt; + int startStmt = lex->index(); + if (!parseStatement(stmt)) { + if (startStmt == lex->index()) + nextToken(); + skipUntilStatement(); + } else + ast->addStatement(stmt); + } + + clearComment(); + + if (lex->lookAhead(0) != '}') { + reportError(i18n("} expected")); + } else + nextToken(); + + UPDATE_POS(ast, start, lex->index()); + node = ast; + + return true; +} + +QString Parser::toString(int start, int end, const QString& sep) const +{ + QStringList l; + + for (int i=start; itokenAt(i); + if (t != Token_comment) + l << t.text(); + } + + return l.join(sep).trimmed(); +} + +bool Parser::parseTypeSpecifierOrClassSpec(TypeSpecifierAST::Node& node) +{ + if (parseClassSpecifier(node)) + return true; + else if (parseEnumSpecifier(node)) + return true; + else if (parseTypeSpecifier(node)) + return true; + + return false; +} + +bool Parser::parseTryBlockStatement(StatementAST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseTryBlockStatement()" << endl; + + int start = lex->index(); + if (lex->lookAhead(0) != Token_try) { + return false; + } + nextToken(); + + StatementAST::Node stmt; + if (!parseCompoundStatement(stmt)) { + syntaxError(); + } + + if (lex->lookAhead(0) != Token_catch) { + reportError(i18n("catch expected")); + } + + CatchStatementListAST::Node list = CreateNode(); + + while (lex->lookAhead(0) == Token_catch) { + + nextToken(); + ADVANCE('(', "("); + ConditionAST::Node cond; + if (!parseCondition(cond)) { + reportError(i18n("condition expected")); + return false; + } + ADVANCE(')', ")"); + + StatementAST::Node body; + if (!parseCompoundStatement(body)) { + syntaxError(); + } + + CatchStatementAST::Node cstmt = CreateNode(); + cstmt->setCondition(cond); + cstmt->setStatement(body); + int l=0, c=0; + if (cond.get()) + cond->getStartPosition(&l, &c); + else if (body.get()) + body->getStartPosition(&l, &c); + + cstmt->setStartPosition(l, c); + if (body.get()) + body->getEndPosition(&l, &c); + + cstmt->setEndPosition(l, c); + list->addStatement(cstmt); + } + + TryBlockStatementAST::Node ast = CreateNode(); + ast->setStatement(stmt); + ast->setCatchStatementList(list); + UPDATE_POS(ast, start, lex->index()); + node = ast; + + return true; +} + +bool Parser::parsePrimaryExpression(AST::Node& /*node*/) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parsePrimarExpression()" << endl; + + + switch (lex->lookAhead(0)) { + case Token_string_literal: { + AST::Node lit; + parseStringLiteral(lit); + } + return true; + + case Token_number_literal: + case Token_char_literal: + case Token_true: + case Token_false: + nextToken(); + return true; + + case Token_this: + nextToken(); + return true; + + case Token_dynamic_cast: + case Token_static_cast: + case Token_reinterpret_cast: + case Token_const_cast: { + nextToken(); + + CHECK('<', "<"); + AST::Node typeId; + parseTypeId(typeId); + CHECK('>', ">"); + + CHECK('(', "("); + AST::Node expr; + parseCommaExpression(expr); + CHECK(')', ")"); + } + return true; + + case Token_typeid: { + nextToken(); + CHECK('(', "("); + AST::Node expr; + parseCommaExpression(expr); + CHECK(')', ")"); + } + return true; + + case '(': { + nextToken(); + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "token = " << lex->lookAhead(0).text() << endl; + AST::Node expr; + if (!parseExpression(expr)) { + return false; + } + CHECK(')', ")"); + } + return true; + + default: { + int start = lex->index(); + TypeSpecifierAST::Node typeSpec; + if (parseSimpleTypeSpecifier(typeSpec) && lex->lookAhead(0) == '(') { + nextToken(); + AST::Node expr; + parseCommaExpression(expr); + CHECK(')', ")"); + return true; + } + + lex->setIndex(start); + NameAST::Node name; + if (parseName(name)) + return true; + } + } + + return false; +} + +bool Parser::parsePostfixExpression(AST::Node& /*node*/) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parsePostfixExpression()" << endl; + + AST::Node expr; + if (!parsePrimaryExpression(expr)) + return false; + + while (true) { + switch (lex->lookAhead(0)) { + case '[': { + nextToken(); + AST::Node e; + parseCommaExpression(e); + CHECK(']', "]"); + } + break; + + case '(': { + nextToken(); + AST::Node funArgs; + parseCommaExpression(funArgs); + CHECK(')', ")"); + } + break; + + case Token_incr: + case Token_decr: + nextToken(); + break; + + case '.': + case Token_arrow: { + nextToken(); + if (lex->lookAhead(0) == Token_template) + nextToken(); + + NameAST::Node name; + if (!parseName(name)) { + return false; + } + } + break; + + case Token_typename: { + nextToken(); + + NameAST::Node name; + if (!parseName(name)) { + return false; + } + + CHECK('(', "("); + AST::Node expr; + parseCommaExpression(expr); + CHECK(')', ")"); + } + return true; + + default: + return true; + + } // end switch + + } // end while + + return true; +} + +bool Parser::parseUnaryExpression(AST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseUnaryExpression()" << endl; + + switch (lex->lookAhead(0)) { + case Token_incr: + case Token_decr: + case '*': + case '&': + case '+': + case '-': + case '!': + case '~': { + nextToken(); + AST::Node expr; + return parseCastExpression(expr); + } + + case Token_sizeof: { + nextToken(); + int index = lex->index(); + if (lex->lookAhead(0) == '(') { + nextToken(); + AST::Node typeId; + if (parseTypeId(typeId) && lex->lookAhead(0) == ')') { + nextToken(); + return true; + } + lex->setIndex(index); + } + AST::Node expr; + return parseUnaryExpression(expr); + } + + case Token_new: + return parseNewExpression(node); + + case Token_delete: + return parseDeleteExpression(node); + } + + return parsePostfixExpression(node); +} + +bool Parser::parseNewExpression(AST::Node& /*node*/) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseNewExpression()" << endl; + if (lex->lookAhead(0) == Token_scope && lex->lookAhead(1) == Token_new) + nextToken(); + + CHECK(Token_new, "new"); + + if (lex->lookAhead(0) == '(') { + nextToken(); + AST::Node expr; + parseCommaExpression(expr); + CHECK(')', ")"); + } + + if (lex->lookAhead(0) == '(') { + nextToken(); + AST::Node typeId; + parseTypeId(typeId); + CHECK(')', ")"); + } else { + AST::Node typeId; + parseNewTypeId(typeId); + } + + AST::Node init; + parseNewInitializer(init); + return true; +} + +bool Parser::parseNewTypeId(AST::Node& /*node*/) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseNewTypeId()" << endl; + TypeSpecifierAST::Node typeSpec; + if (parseTypeSpecifier(typeSpec)) { + AST::Node declarator; + parseNewDeclarator(declarator); + return true; + } + + return false; +} + +bool Parser::parseNewDeclarator(AST::Node& /*node*/) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseNewDeclarator()" << endl; + AST::Node ptrOp; + if (parsePtrOperator(ptrOp)) { + AST::Node declarator; + parseNewDeclarator(declarator); + return true; + } + + if (lex->lookAhead(0) == '[') { + while (lex->lookAhead(0) == '[') { + nextToken(); + AST::Node expr; + parseExpression(expr); + ADVANCE(']', "]"); + } + return true; + } + + return false; +} + +bool Parser::parseNewInitializer(AST::Node& /*node*/) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseNewInitializer()" << endl; + if (lex->lookAhead(0) != '(') + return false; + + nextToken(); + AST::Node expr; + parseCommaExpression(expr); + CHECK(')', ")"); + + return true; +} + +bool Parser::parseDeleteExpression(AST::Node& /*node*/) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseDeleteExpression()" << endl; + if (lex->lookAhead(0) == Token_scope && lex->lookAhead(1) == Token_delete) + nextToken(); + + CHECK(Token_delete, "delete"); + + if (lex->lookAhead(0) == '[') { + nextToken(); + CHECK(']', "]"); + } + + AST::Node expr; + return parseCastExpression(expr); +} + +bool Parser::parseCastExpression(AST::Node& /*node*/) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseCastExpression()" << endl; + + int index = lex->index(); + + if (lex->lookAhead(0) == '(') { + nextToken(); + AST::Node typeId; + if (parseTypeId(typeId)) { + if (lex->lookAhead(0) == ')') { + nextToken(); + AST::Node expr; + if (parseCastExpression(expr)) + return true; + } + } + } + + lex->setIndex(index); + + AST::Node expr; + return parseUnaryExpression(expr); +} + +bool Parser::parsePmExpression(AST::Node& /*node*/) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser:parsePmExpression()" << endl; + AST::Node expr; + if (!parseCastExpression(expr)) + return false; + + while (lex->lookAhead(0) == Token_ptrmem) { + nextToken(); + + if (!parseCastExpression(expr)) + return false; + } + + return true; +} + +bool Parser::parseMultiplicativeExpression(AST::Node& /*node*/) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseMultiplicativeExpression()" << endl; + AST::Node expr; + if (!parsePmExpression(expr)) + return false; + + while (lex->lookAhead(0) == '*' || lex->lookAhead(0) == '/' || lex->lookAhead(0) == '%') { + nextToken(); + + if (!parsePmExpression(expr)) + return false; + } + + return true; +} + + +bool Parser::parseAdditiveExpression(AST::Node& /*node*/) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseAdditiveExpression()" << endl; + AST::Node expr; + if (!parseMultiplicativeExpression(expr)) + return false; + + while (lex->lookAhead(0) == '+' || lex->lookAhead(0) == '-') { + nextToken(); + + if (!parseMultiplicativeExpression(expr)) + return false; + } + + return true; +} + +bool Parser::parseShiftExpression(AST::Node& /*node*/) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseShiftExpression()" << endl; + AST::Node expr; + if (!parseAdditiveExpression(expr)) + return false; + + while (lex->lookAhead(0) == Token_shift || (lex->lookAhead(0) == '>' && lex->lookAhead(1) == '>')) { + nextToken(); + + if (!parseAdditiveExpression(expr)) + return false; + } + + return true; +} + +bool Parser::parseRelationalExpression(AST::Node& /*node*/, bool templArgs) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseRelationalExpression()" << endl; + AST::Node expr; + if (!parseShiftExpression(expr)) + return false; + + while (lex->lookAhead(0) == '<' || (lex->lookAhead(0) == '>' && !templArgs) || + lex->lookAhead(0) == Token_leq || lex->lookAhead(0) == Token_geq) { + nextToken(); + + if (!parseShiftExpression(expr)) + return false; + } + + return true; +} + +bool Parser::parseEqualityExpression(AST::Node& /*node*/, bool templArgs) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseEqualityExpression()" << endl; + AST::Node expr; + if (!parseRelationalExpression(expr, templArgs)) + return false; + + while (lex->lookAhead(0) == Token_eq || lex->lookAhead(0) == Token_not_eq) { + nextToken(); + + if (!parseRelationalExpression(expr, templArgs)) + return false; + } + + return true; +} + +bool Parser::parseAndExpression(AST::Node& /*node*/, bool templArgs) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseAndExpression()" << endl; + AST::Node expr; + if (!parseEqualityExpression(expr, templArgs)) + return false; + + while (lex->lookAhead(0) == '&') { + nextToken(); + + if (!parseEqualityExpression(expr, templArgs)) + return false; + } + + return true; +} + +bool Parser::parseExclusiveOrExpression(AST::Node& /*node*/, bool templArgs) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseExclusiveOrExpression()" << endl; + AST::Node expr; + if (!parseAndExpression(expr, templArgs)) + return false; + + while (lex->lookAhead(0) == '^') { + nextToken(); + + if (!parseAndExpression(expr, templArgs)) + return false; + } + + return true; +} + +bool Parser::parseInclusiveOrExpression(AST::Node& /*node*/, bool templArgs) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseInclusiveOrExpression()" << endl; + AST::Node expr; + if (!parseExclusiveOrExpression(expr, templArgs)) + return false; + + while (lex->lookAhead(0) == '|') { + nextToken(); + + if (!parseExclusiveOrExpression(expr, templArgs)) + return false; + } + + return true; +} + +bool Parser::parseLogicalAndExpression(AST::Node& /*node*/, bool templArgs) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseLogicalAndExpression()" << endl; + + AST::Node expr; + if (!parseInclusiveOrExpression(expr, templArgs)) + return false; + + while (lex->lookAhead(0) == Token_and) { + nextToken(); + + if (!parseInclusiveOrExpression(expr, templArgs)) + return false; + } + + return true; +} + +bool Parser::parseLogicalOrExpression(AST::Node& node, bool templArgs) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseLogicalOrExpression()" << endl; + + int start = lex->index(); + + AST::Node expr; + if (!parseLogicalAndExpression(expr, templArgs)) + return false; + + while (lex->lookAhead(0) == Token_or) { + nextToken(); + + if (!parseLogicalAndExpression(expr, templArgs)) + return false; + } + + AST::Node ast = CreateNode(); + UPDATE_POS(ast, start, lex->index()); + node = ast; + return true; +} + +bool Parser::parseConditionalExpression(AST::Node& /*node*/) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseConditionalExpression()" << endl; + AST::Node expr; + if (!parseLogicalOrExpression(expr)) + return false; + + if (lex->lookAhead(0) == '?') { + nextToken(); + + if (!parseExpression(expr)) + return false; + + CHECK(':', ":"); + + if (!parseAssignmentExpression(expr)) + return false; + } + + return true; +} + +bool Parser::parseAssignmentExpression(AST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseAssignmentExpression()" << endl; + int start = lex->index(); + AST::Node expr; + if (lex->lookAhead(0) == Token_throw && !parseThrowExpression(expr)) + return false; + else if (!parseConditionalExpression(expr)) + return false; + + while (lex->lookAhead(0) == Token_assign || lex->lookAhead(0) == '=') { + nextToken(); + + if (!parseConditionalExpression(expr)) + return false; + } + + AST::Node ast = CreateNode(); + UPDATE_POS(ast, start, lex->index()); + node = ast; + return true; +} + +bool Parser::parseConstantExpression(AST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseConstantExpression()" << endl; + int start = lex->index(); + if (parseConditionalExpression(node)) { + AST::Node ast = CreateNode(); + UPDATE_POS(ast, start, lex->index()); + node = ast; + return true; + } + return false; +} + +bool Parser::parseExpression(AST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseExpression()" << endl; + + int start = lex->index(); + + if (!parseCommaExpression(node)) + return false; + + AST::Node ast = CreateNode(); + UPDATE_POS(ast, start, lex->index()); + node = ast; + return true; +} + +bool Parser::parseCommaExpression(AST::Node& node) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseCommaExpression()" << endl; + int start = lex->index(); + + AST::Node expr; + if (!parseAssignmentExpression(expr)) + return false; + + while (lex->lookAhead(0) == ',') { + nextToken(); + + if (!parseAssignmentExpression(expr)) + return false; + } + + AST::Node ast = CreateNode(); + UPDATE_POS(ast, start, lex->index()); + node = ast; + return true; +} + +bool Parser::parseThrowExpression(AST::Node& /*node*/) +{ + DEBUG("Parser") << "--- tok = " << lex->lookAhead(0).text() << " -- " << "Parser::parseThrowExpression()" << endl; + if (lex->lookAhead(0) != Token_throw) + return false; + + CHECK(Token_throw, "throw"); + AST::Node expr; + if (!parseAssignmentExpression(expr)) + return false; + + return true; +} + +bool Parser::parseIvarDeclList(AST::Node & node) +{ + Q_UNUSED(node); + return false; +} + +bool Parser::parseIvarDecls(AST::Node & node) +{ + Q_UNUSED(node); + return false; +} + +bool Parser::parseIvarDecl(AST::Node & node) +{ + Q_UNUSED(node); + return false; +} + +bool Parser::parseIvars(AST::Node & node) +{ + Q_UNUSED(node); + return false; +} + +bool Parser::parseIvarDeclarator(AST::Node & node) +{ + Q_UNUSED(node); + return false; +} + +bool Parser::parseMethodDecl(AST::Node & node) +{ + Q_UNUSED(node); + return false; +} + +bool Parser::parseUnarySelector(AST::Node & node) +{ + Q_UNUSED(node); + return false; +} + +bool Parser::parseKeywordSelector(AST::Node & node) +{ + Q_UNUSED(node); + return false; +} + +bool Parser::parseSelector(AST::Node & node) +{ + Q_UNUSED(node); + return false; +} + +bool Parser::parseKeywordDecl(AST::Node & node) +{ + Q_UNUSED(node); + return false; +} + +bool Parser::parseReceiver(AST::Node & node) +{ + Q_UNUSED(node); + return false; +} + +bool Parser::parseObjcMessageExpr(AST::Node & node) +{ + Q_UNUSED(node); + return false; +} + +bool Parser::parseMessageArgs(AST::Node & node) +{ + Q_UNUSED(node); + return false; +} + +bool Parser::parseKeywordExpr(AST::Node & node) +{ + Q_UNUSED(node); + return false; +} + +bool Parser::parseKeywordArgList(AST::Node & node) +{ + Q_UNUSED(node); + return false; +} + +bool Parser::parseKeywordArg(AST::Node & node) +{ + Q_UNUSED(node); + return false; +} + +bool Parser::parseReservedWord(AST::Node & node) +{ + Q_UNUSED(node); + return false; +} + +bool Parser::parseMyParms(AST::Node & node) +{ + Q_UNUSED(node); + return false; +} + +bool Parser::parseMyParm(AST::Node & node) +{ + Q_UNUSED(node); + return false; +} + +bool Parser::parseOptParmList(AST::Node & node) +{ + Q_UNUSED(node); + return false; +} + +bool Parser::parseObjcSelectorExpr(AST::Node & node) +{ + Q_UNUSED(node); + return false; +} + +bool Parser::parseSelectorArg(AST::Node & node) +{ + Q_UNUSED(node); + return false; +} + +bool Parser::parseKeywordNameList(AST::Node & node) +{ + Q_UNUSED(node); + return false; +} + +bool Parser::parseKeywordName(AST::Node & node) +{ + Q_UNUSED(node); + return false; +} + +bool Parser::parseObjcEncodeExpr(AST::Node & node) +{ + Q_UNUSED(node); + return false; +} + +bool Parser::parseObjcString(AST::Node & node) +{ + Q_UNUSED(node); + return false; +} + +bool Parser::parseProtocolRefs(AST::Node & node) +{ + Q_UNUSED(node); + return false; +} + +bool Parser::parseIdentifierList(GroupAST::Node & node) +{ + int start = lex->index(); + + if (lex->lookAhead(0) != Token_identifier) + return false; + + GroupAST::Node ast = CreateNode(); + + AST_FROM_TOKEN(tk, lex->index()); + ast->addNode(tk); + nextToken(); + + while (lex->lookAhead(0) == ',') { + nextToken(); + if (lex->lookAhead(0) == Token_identifier) { + AST_FROM_TOKEN(tk, lex->index()); + ast->addNode(tk); +// nextToken(); + } + ADVANCE(Token_identifier, "identifier"); + } + + node = ast; + UPDATE_POS(node, start, lex->index()); + return true; +} + +bool Parser::parseIdentifierColon(AST::Node & node) +{ + Q_UNUSED(node); + + if (lex->lookAhead(0) == Token_identifier && lex->lookAhead(1) == ':') { + nextToken(); + nextToken(); + return true; + } // ### else if PTYPENAME -> return true ; + + return false; +} + +bool Parser::parseObjcProtocolExpr(AST::Node & node) +{ + Q_UNUSED(node); + return false; +} + +bool Parser::parseObjcOpenBracketExpr(AST::Node & node) +{ + Q_UNUSED(node); + return false; +} + +bool Parser::parseObjcCloseBracket(AST::Node & node) +{ + Q_UNUSED(node); + return false; +} + +bool Parser::parseObjcDef(DeclarationAST::Node & node) +{ + Q_UNUSED(node); + return false; +} + +bool Parser::parseObjcClassDef(DeclarationAST::Node & node) +{ + Q_UNUSED(node); + return false; +} + +bool Parser::parseObjcClassDecl(DeclarationAST::Node & node) +{ + Q_UNUSED(node); + + ADVANCE(OBJC_CLASS, "@class"); + + GroupAST::Node idList; + if (!parseIdentifierList(idList)) + return false; + + ADVANCE(';', ";"); + + return true; +} + +bool Parser::parseObjcProtocolDecl(DeclarationAST::Node & node) +{ + Q_UNUSED(node); + + ADVANCE(OBJC_PROTOCOL, "@protocol"); + + GroupAST::Node idList; + if (!parseIdentifierList(idList)) + return false; + + ADVANCE(';', ";"); + + return true; +} + +bool Parser::parseObjcAliasDecl(DeclarationAST::Node & node) +{ + Q_UNUSED(node); + + ADVANCE(OBJC_ALIAS, "@alias"); + + GroupAST::Node idList; + if (!parseIdentifierList(idList)) + return false; + + ADVANCE(';', ";"); + + return true; +} + +bool Parser::parseObjcProtocolDef(DeclarationAST::Node & node) +{ + Q_UNUSED(node); + return false; +} + +bool Parser::parseObjcMethodDef(DeclarationAST::Node & node) +{ + Q_UNUSED(node); + return false; +} + +bool Parser::parseWinDeclSpec(GroupAST::Node & node) +{ + if (lex->lookAhead(0) == Token_identifier && lex->lookAhead(0).text() == "__declspec" && lex->lookAhead(1) == '(' && lex->lookAhead(2) != ')') { + int start = lex->index(); + nextToken(); + nextToken(); // skip '(' + + if (!parseIdentifierList(node)) + return false; + + ADVANCE(')', ")"); + + UPDATE_POS(node, start, lex->index()); + return true; + } + + return false; +} + diff -Nru umbrello-4.12.3/lib/cppparser/parser.h umbrello-4.12.90/lib/cppparser/parser.h --- umbrello-4.12.3/lib/cppparser/parser.h 1970-01-01 00:00:00.000000000 +0000 +++ umbrello-4.12.90/lib/cppparser/parser.h 2014-03-05 15:04:09.000000000 +0000 @@ -0,0 +1,480 @@ +/* This file is part of KDevelop + Copyright (C) 2002, 2003 Roberto Raggi + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef PARSER_H +#define PARSER_H + +#include "ast.h" + +#include +#include +#include +#include +#include + +struct ParserPrivateData; + +class Driver; +class Lexer; +class Token; +struct Error; + + +class CommentFormatter +{ + static inline bool isWhite(QChar c) + { + return c.isSpace(); + } + + static void rStrip(QString str, QString& from) + { + if (str.isEmpty()) return; + + int i = 0; + int ip = from.length(); + int s = from.length(); + + for (int a = s-1; a >= 0; a--) { + if (isWhite(from[a])) { + continue; + } else { + if (from[a] == str[i]) { + i++; + ip = a; + if (i == (int)str.length()) break; + } else { + break; + } + } + } + + if (ip != (int)from.length()) from = from.left(ip); + } + + static void strip(QString str, QString& from) + { + if (str.isEmpty()) return; + + int i = 0; + int ip = 0; + int s = from.length(); + + for (int a = 0; a < s; a++) { + if (isWhite(from[a])) { + continue; + } else { + if (from[a] == str[i]) { + i++; + ip = a+1; + if (i == (int)str.length()) break; + } else { + break; + } + } + } + + if (ip) from = from.mid(ip); + } + +public: + + static QString formatComment(QString comment) + { + QString ret; + int i = 0; + int s = comment.length(); + while (i < s && comment[i] == '/') { + i++; + } + + if (i > 1) { + ret = comment.mid(i); + } else { + ///remove the star in each line + QStringList lines = comment.split("\n"); + + if (lines.isEmpty()) return ret; + + strip("/**", lines.front()); + rStrip("/**", lines.back()); + + QStringList::iterator it = lines.begin(); + ++it; + QStringList::iterator eit = lines.end(); + + if (it != lines.end()) { + --eit; + + for (; it != eit; ++it) { + strip("*", *it); + } + + if (lines.front().trimmed().isEmpty()) + lines.pop_front(); + + if (lines.back().trimmed().isEmpty()) + lines.pop_back(); + } + + ret = lines.join("\n"); + } + + return ret; + } +}; + +class Comment +{ + QString m_text; + int m_line; + bool m_formatted; + + + void format() + { + if (m_formatted) return; + m_formatted = true; + m_text = CommentFormatter::formatComment(m_text); + } + +public: + Comment(QString text = "", int line = -1) : m_text(text), m_line(line), m_formatted(false) + { + } + + Comment(int line) : m_line(line) + { + } + + void operator += (Comment rhs) + { + format(); + rhs.format(); + m_text += " " + rhs.m_text; + } + + operator bool() const + { + return !m_text.isEmpty(); + } + + operator QString() + { + format(); + return m_text; + } + + inline int line() const + { + return m_line; + } + + bool operator < (Comment& rhs) const + { + return m_line < rhs.m_line; + } + + bool isSame (const Comment& rhs) + { + if (rhs.m_formatted) format(); + return m_text == rhs.m_text; + } + + struct cmp { + bool operator () (const Comment& c1, const Comment& c2) const + { + return c1.line() < c2.line(); + } + }; +}; + + +class CommentStore +{ +private: + typedef std::set< Comment, Comment::cmp > CommentSet; + CommentSet m_comments; + +public: + + ///Returns the comment nearest to "end"(inclusive), and returns & removes it + Comment getCommentInRange(int end, int start = 0) + { + CommentSet::iterator it = m_comments.lower_bound(end); + + + while (it != m_comments.begin() && (*it).line() > end) { + --it; + } + + if (it != m_comments.end() && (*it).line() >= start && (*it).line() <= end) { + Comment ret = *it; + m_comments.erase(it); + return ret; + } else { + return Comment(); + } + } + + ///Returns and removes the comment in the line + Comment getComment(int line) + { + CommentSet::iterator it = m_comments.find(line); + if (it != m_comments.end()) { + Comment ret = *it; + m_comments.erase(it); + return ret; + } else { + return Comment(); + } + } + + void addComment(Comment comment) + { + + CommentSet::iterator it = m_comments.find(comment); + if (it != m_comments.end()) { + if (comment.isSame(*it)) return; + Comment c = *it; + c += comment; + comment = c; + m_comments.erase(it); + } + + m_comments.insert(comment); + } + + ///Does not delete the comment + Comment latestComment() + { + CommentSet::iterator it = m_comments.end(); + if (it == m_comments.begin()) return Comment(); + --it; + return *it; + } + + void clear() + { + m_comments.clear(); + } +}; + + +class Parser +{ +public: + Parser(Driver* driver, Lexer* lexer); + virtual ~Parser(); + +private: + virtual bool reportError(const Error& err); + /** @todo remove*/ virtual bool reportError(const QString& msg); + /** @todo remove*/ virtual void syntaxError(); + +public /*rules*/ : + + bool parseTranslationUnit(TranslationUnitAST::Node& node); + + bool parseDeclaration(DeclarationAST::Node& node); + bool parseBlockDeclaration(DeclarationAST::Node& node); + bool parseLinkageSpecification(DeclarationAST::Node& node); + bool parseLinkageBody(LinkageBodyAST::Node& node); + bool parseNamespace(DeclarationAST::Node& node); + bool parseNamespaceAliasDefinition(DeclarationAST::Node& node); + bool parseUsing(DeclarationAST::Node& node); + bool parseUsingDirective(DeclarationAST::Node& node); + bool parseTypedef(DeclarationAST::Node& node); + bool parseAsmDefinition(DeclarationAST::Node& node); + bool parseTemplateDeclaration(DeclarationAST::Node& node); + bool parseDeclarationInternal(DeclarationAST::Node& node); + + bool parseUnqualifiedName(ClassOrNamespaceNameAST::Node& node); + bool parseStringLiteral(AST::Node& node); + bool parseName(NameAST::Node& node); + bool parseOperatorFunctionId(AST::Node& node); + bool parseTemplateArgumentList(TemplateArgumentListAST::Node& node, bool reportError=true); + bool parseOperator(AST::Node& node); + bool parseCvQualify(GroupAST::Node& node); + bool parseSimpleTypeSpecifier(TypeSpecifierAST::Node& node); + bool parsePtrOperator(AST::Node& node); + bool parseTemplateArgument(AST::Node& node); + bool parseTypeSpecifier(TypeSpecifierAST::Node& node); + bool parseTypeSpecifierOrClassSpec(TypeSpecifierAST::Node& node); + bool parseDeclarator(DeclaratorAST::Node& node); + bool parseTemplateParameterList(TemplateParameterListAST::Node& node); + bool parseTemplateParameter(TemplateParameterAST::Node& node); + bool parseStorageClassSpecifier(GroupAST::Node& node); + bool parseFunctionSpecifier(GroupAST::Node& node); + bool parseInitDeclaratorList(InitDeclaratorListAST::Node& node); + bool parseInitDeclarator(InitDeclaratorAST::Node& node); + bool parseParameterDeclarationClause(ParameterDeclarationClauseAST::Node& node); + bool parseCtorInitializer(AST::Node& node); + bool parsePtrToMember(AST::Node& node); + bool parseEnumSpecifier(TypeSpecifierAST::Node& node); + bool parseClassSpecifier(TypeSpecifierAST::Node& node); + bool parseWinDeclSpec(GroupAST::Node& node); + bool parseElaboratedTypeSpecifier(TypeSpecifierAST::Node& node); + bool parseDeclaratorId(NameAST::Node& node); + bool parseExceptionSpecification(GroupAST::Node& node); + bool parseEnumerator(EnumeratorAST::Node& node); + bool parseTypeParameter(TypeParameterAST::Node& node); + bool parseParameterDeclaration(ParameterDeclarationAST::Node& node); + bool parseTypeId(AST::Node& node); + bool parseAbstractDeclarator(DeclaratorAST::Node& node); + bool parseParameterDeclarationList(ParameterDeclarationListAST::Node& node); + bool parseMemberSpecification(DeclarationAST::Node& node); + bool parseAccessSpecifier(AST::Node& node); + bool parseTypeIdList(GroupAST::Node& node); + bool parseMemInitializerList(AST::Node& node); + bool parseMemInitializer(AST::Node& node); + bool parseInitializer(AST::Node& node); + bool parseBaseClause(BaseClauseAST::Node& node); + bool parseBaseSpecifier(BaseSpecifierAST::Node& node); + bool parseInitializerClause(AST::Node& node); + bool parseMemInitializerId(NameAST::Node& node); + bool parseFunctionBody(StatementListAST::Node& node); + + // expression + bool skipExpression(AST::Node& node); + bool skipCommaExpression(AST::Node& node); + bool skipExpressionStatement(StatementAST::Node& node); + + bool parseExpression(AST::Node& node); + bool parsePrimaryExpression(AST::Node& node); + bool parsePostfixExpression(AST::Node& node); + bool parseUnaryExpression(AST::Node& node); + bool parseNewExpression(AST::Node& node); + bool parseNewTypeId(AST::Node& node); + bool parseNewDeclarator(AST::Node& node); + bool parseNewInitializer(AST::Node& node); + bool parseDeleteExpression(AST::Node& node); + bool parseCastExpression(AST::Node& node); + bool parsePmExpression(AST::Node& node); + bool parseMultiplicativeExpression(AST::Node& node); + bool parseAdditiveExpression(AST::Node& node); + bool parseShiftExpression(AST::Node& node); + bool parseRelationalExpression(AST::Node& node, bool templArgs=false); + bool parseEqualityExpression(AST::Node& node, bool templArgs=false); + bool parseAndExpression(AST::Node& node, bool templArgs=false); + bool parseExclusiveOrExpression(AST::Node& node, bool templArgs=false); + bool parseInclusiveOrExpression(AST::Node& node, bool templArgs=false); + bool parseLogicalAndExpression(AST::Node& node, bool templArgs=false); + bool parseLogicalOrExpression(AST::Node& node, bool templArgs=false); + bool parseConditionalExpression(AST::Node& node); + bool parseAssignmentExpression(AST::Node& node); + bool parseConstantExpression(AST::Node& node); + bool parseCommaExpression(AST::Node& node); + bool parseThrowExpression(AST::Node& node); + + // statement + bool parseCondition(ConditionAST::Node& node); + bool parseStatement(StatementAST::Node& node); + bool parseWhileStatement(StatementAST::Node& node); + bool parseDoStatement(StatementAST::Node& node); + bool parseForStatement(StatementAST::Node& node); + bool parseForEachStatement(StatementAST::Node& node); // qt4 [erbsland] + bool parseCompoundStatement(StatementAST::Node& node); + bool parseForInitStatement(StatementAST::Node& node); + bool parseIfStatement(StatementAST::Node& node); + bool parseSwitchStatement(StatementAST::Node& node); + bool parseLabeledStatement(StatementAST::Node& node); + bool parseDeclarationStatement(StatementAST::Node& node); + bool parseTryBlockStatement(StatementAST::Node& node); + + // objective c + bool parseObjcDef(DeclarationAST::Node& node); + bool parseObjcClassDef(DeclarationAST::Node& node); + bool parseObjcClassDecl(DeclarationAST::Node& node); + bool parseObjcProtocolDecl(DeclarationAST::Node& node); + bool parseObjcAliasDecl(DeclarationAST::Node& node); + bool parseObjcProtocolDef(DeclarationAST::Node& node); + bool parseObjcMethodDef(DeclarationAST::Node& node); + + bool parseIvarDeclList(AST::Node& node); + bool parseIvarDecls(AST::Node& node); + bool parseIvarDecl(AST::Node& node); + bool parseIvars(AST::Node& node); + bool parseIvarDeclarator(AST::Node& node); + bool parseMethodDecl(AST::Node& node); + bool parseUnarySelector(AST::Node& node); + bool parseKeywordSelector(AST::Node& node); + bool parseSelector(AST::Node& node); + bool parseKeywordDecl(AST::Node& node); + bool parseReceiver(AST::Node& node); + bool parseObjcMessageExpr(AST::Node& node); + bool parseMessageArgs(AST::Node& node); + bool parseKeywordExpr(AST::Node& node); + bool parseKeywordArgList(AST::Node& node); + bool parseKeywordArg(AST::Node& node); + bool parseReservedWord(AST::Node& node); + bool parseMyParms(AST::Node& node); + bool parseMyParm(AST::Node& node); + bool parseOptParmList(AST::Node& node); + bool parseObjcSelectorExpr(AST::Node& node); + bool parseSelectorArg(AST::Node& node); + bool parseKeywordNameList(AST::Node& node); + bool parseKeywordName(AST::Node& node); + bool parseObjcEncodeExpr(AST::Node& node); + bool parseObjcString(AST::Node& node); + bool parseProtocolRefs(AST::Node& node); + bool parseIdentifierList(GroupAST::Node& node); + bool parseIdentifierColon(AST::Node& node); + bool parseObjcProtocolExpr(AST::Node& node); + bool parseObjcOpenBracketExpr(AST::Node& node); + bool parseObjcCloseBracket(AST::Node& node); + + void nextToken(bool skipComments = true); + + ///parses all comments until the end of the line + Comment comment(); + void preparseLineComments(int line); + void processComment(int offset = 0); + void clearComment(); + + bool skipUntil(int token); + bool skipUntilDeclaration(); + bool skipUntilStatement(); + bool skip(int l, int r); + QString toString(int start, int end, const QString& sep=" ") const; + +private: + int currentLine(); + CommentStore m_commentStore; + + template + void eventuallyTakeComment(int startLn, int line, Type& ast); + template + void eventuallyTakeComment(Type& ast); + + ParserPrivateData* d; + Driver* m_driver; + Lexer* lex; + Comment m_currentComment; + int m_problems; + int m_maxProblems; + bool objcp; + +private: + Parser(const Parser& source); + void operator = (const Parser& source); +}; + + +#endif diff -Nru umbrello-4.12.3/lib/cppparser/README umbrello-4.12.90/lib/cppparser/README --- umbrello-4.12.3/lib/cppparser/README 1970-01-01 00:00:00.000000000 +0000 +++ umbrello-4.12.90/lib/cppparser/README 2014-03-05 15:04:09.000000000 +0000 @@ -0,0 +1,56 @@ +This directory contains the C++ parser from Kdevelop-3.0. + +Following files are copies from the directory kdevelop/lib/cppparser: + ast.{h,cpp} driver.{h,cpp} errors.{h,cpp} keywords.lut.h lexer.{h,cpp} + lookup.{h,cpp} parser.{h,cpp} tree_parser.{h,cpp} + +Following files are copies from the directory kdevelop/languages/cpp: + ast_utils.{h,cpp} + +Following files are copies from the directory kdevelop/lib/util: + urlutil.{h,cpp} + +The source files cpptree2uml.{h,cpp} are based on kdevelop/languages/cpp/ +store_walker.{h,cpp}. The class CppTree2Uml inherits from class TreeParser +and overrides certain methods from that class. + +CppTree2Uml visits the nodes of the abstract syntax tree constructed by the +CppParser, and constructs UML objects on the way. + +The import_utils.h (in the parent directory) is the interface between the +CppTree2Uml and Umbrello. +import_utils implements the construction of the UML objects. CppTree2Uml calls +the create/insert methods in the import_utils while traversing the syntax +tree. + +The one and only method that Umbrello uses for accessing the C++ parser, +and any other parser for that matter, is ClassImport::importFiles(). +The class CppImport (in the parent directory) implements that operation. +Thus we have these classes: + + +-------------------+ + | <> | + | ClassImport | + +===================+ +Umbrello ------>| importFiles() = 0 | + +-------------------+ + A + | <> + | + +-------------------+ +-------------------+ + | CppImport | | CppTree2Uml | + +===================+ <> +===================+ + | importFiles() |-------------->| | + +-------------------+ | | + +-------------------+ + | + +-------------------+ | + | <> | | + | Import_Utils | | + +===================+ | + | createUMLObject() | <> | + | insertMethod() |<-----------------------+ + | insertAttribute() | + +-------------------+ + | +Umbrello <--------------+ diff -Nru umbrello-4.12.3/lib/cppparser/tree_parser.cpp umbrello-4.12.90/lib/cppparser/tree_parser.cpp --- umbrello-4.12.3/lib/cppparser/tree_parser.cpp 1970-01-01 00:00:00.000000000 +0000 +++ umbrello-4.12.90/lib/cppparser/tree_parser.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -0,0 +1,215 @@ +/* This file is part of KDevelop + Copyright (C) 2002, 2003 Roberto Raggi + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include "debug_utils.h" +#include "tree_parser.h" +#include "driver.h" + +#include + +DEBUG_REGISTER_DISABLED(TreeParser) + +TreeParser::TreeParser() +{ +} + +TreeParser::~TreeParser() +{ +} + +void TreeParser::parseTranslationUnit(const ParsedFile& translationUnit) +{ + DEBUG("TreeParser") << "TreeParser::parseTranslationUnit()" << endl; + + QList declarations = translationUnit->declarationList(); + QList::const_iterator it = declarations.constBegin(); + for (; it != declarations.constEnd(); it++) { + if ((*it) == 0) { + //kdDebug(9007) << "declaration is zero" << endl; + continue; + } + parseDeclaration(*it); + } +} + +void TreeParser::parseDeclaration(DeclarationAST* declaration) +{ + DEBUG("TreeParser") << "TreeParser::parseDeclaration()" << endl; + + if (!declaration) + return; + + switch (declaration->nodeType()) { + case NodeType_LinkageSpecification: + parseLinkageSpecification(static_cast(declaration)); + break; + + case NodeType_Namespace: + parseNamespace(static_cast(declaration)); + break; + + case NodeType_NamespaceAlias: + parseNamespaceAlias(static_cast(declaration)); + break; + + case NodeType_Using: + parseUsing(static_cast(declaration)); + break; + + case NodeType_UsingDirective: + parseUsingDirective(static_cast(declaration)); + break; + + case NodeType_Typedef: + parseTypedef(static_cast(declaration)); + break; + + case NodeType_TemplateDeclaration: + parseTemplateDeclaration(static_cast(declaration)); + break; + + case NodeType_SimpleDeclaration: + parseSimpleDeclaration(static_cast(declaration)); + break; + + case NodeType_FunctionDefinition: + parseFunctionDefinition(static_cast(declaration)); + break; + + case NodeType_AccessDeclaration: + parseAccessDeclaration(static_cast(declaration)); + break; + } +} + +void TreeParser::parseLinkageSpecification(LinkageSpecificationAST* ast) +{ + DEBUG("TreeParser") << "TreeParser::parseLinkageSpecification()" << endl; + if (ast->linkageBody()) + parseLinkageBody(ast->linkageBody()); + else if (ast->declaration()) + parseDeclaration(ast->declaration()); +} + +void TreeParser::parseNamespace(NamespaceAST* decl) +{ + DEBUG("TreeParser") << "TreeParser::parseNamespace()" << endl; + if (decl->linkageBody()) + parseLinkageBody(decl->linkageBody()); +} + +void TreeParser::parseNamespaceAlias(NamespaceAliasAST* decl) +{ + DEBUG("TreeParser") << "TreeParser::parseNamespaceAlias()" << endl; + Q_UNUSED(decl); +} + +void TreeParser::parseUsing(UsingAST* decl) +{ + DEBUG("TreeParser") << "TreeParser::parseUsing()" << endl; + Q_UNUSED(decl); +} + +void TreeParser::parseUsingDirective(UsingDirectiveAST* decl) +{ + DEBUG("TreeParser") << "TreeParser::parseUsingDirective()" << endl; + Q_UNUSED(decl); +} + +void TreeParser::parseTypedef(TypedefAST* decl) +{ + DEBUG("TreeParser") << "TreeParser::parseTypedef()" << endl; + if (decl->typeSpec()) + parseTypeSpecifier(decl->typeSpec()); +} + +void TreeParser::parseTemplateDeclaration(TemplateDeclarationAST* decl) +{ + DEBUG("TreeParser") << "TreeParser::parseTemplateDeclaration()" << endl; + Q_UNUSED(decl); +} + +void TreeParser::parseSimpleDeclaration(SimpleDeclarationAST* decl) +{ + DEBUG("TreeParser") << "TreeParser::parseSimpleDeclaration()" << endl; + Q_UNUSED(decl); +} + +void TreeParser::parseFunctionDefinition(FunctionDefinitionAST* def) +{ + DEBUG("TreeParser") << "TreeParser::parseFunctionDefinition()" << endl; + Q_UNUSED(def); +} + +void TreeParser::parseLinkageBody(LinkageBodyAST* linkageBody) +{ + DEBUG("TreeParser") << "TreeParser::parseLinkageBody()" << endl; + QList declarations = linkageBody->declarationList(); + QList::const_iterator it = declarations.constBegin(); + for (; it != declarations.constEnd(); ++it) { + parseDeclaration(*it); + } +} + +void TreeParser::parseTypeSpecifier(TypeSpecifierAST* typeSpec) +{ + DEBUG("TreeParser") << "TreeParser::parseTypeSpecifier()" << endl; + switch (typeSpec->nodeType()) { + case NodeType_ClassSpecifier: + parseClassSpecifier(static_cast(typeSpec)); + break; + + case NodeType_EnumSpecifier: + parseEnumSpecifier(static_cast(typeSpec)); + break; + + case NodeType_ElaboratedTypeSpecifier: + parseElaboratedTypeSpecifier(static_cast(typeSpec)); + break; + } +} + +void TreeParser::parseClassSpecifier(ClassSpecifierAST* classSpec) +{ + DEBUG("TreeParser") << "TreeParser::parseClassSpecifier()" << endl; + QList declarations = classSpec->declarationList(); + QList::const_iterator it = declarations.constBegin(); + for (; it != declarations.constEnd(); ++it) { + parseDeclaration(*it); + } +} + +void TreeParser::parseEnumSpecifier(EnumSpecifierAST* enumSpec) +{ + DEBUG("TreeParser") << "TreeParser::parseEnumSpecifier()" << endl; + Q_UNUSED(enumSpec); +} + +void TreeParser::parseElaboratedTypeSpecifier(ElaboratedTypeSpecifierAST* typeSpec) +{ + DEBUG("TreeParser") << "TreeParser::parseElaboratedTypeSpecifier()" << endl; + Q_UNUSED(typeSpec); +} + +void TreeParser::parseAccessDeclaration (AccessDeclarationAST * access) +{ + DEBUG("TreeParser") << "TreeParser::parseAccessDeclaration()" << endl; + Q_UNUSED(access); +} + diff -Nru umbrello-4.12.3/lib/cppparser/tree_parser.h umbrello-4.12.90/lib/cppparser/tree_parser.h --- umbrello-4.12.3/lib/cppparser/tree_parser.h 1970-01-01 00:00:00.000000000 +0000 +++ umbrello-4.12.90/lib/cppparser/tree_parser.h 2014-03-05 15:04:09.000000000 +0000 @@ -0,0 +1,60 @@ +/* This file is part of KDevelop + Copyright (C) 2002, 2003 Roberto Raggi + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef __tree_parser_h +#define __tree_parser_h + +#include "ast.h" +class ParsedFile; + +class TreeParser +{ +public: + TreeParser(); + virtual ~TreeParser(); + + // translation-unit + virtual void parseTranslationUnit(const ParsedFile&); + + // declarations + virtual void parseDeclaration(DeclarationAST*); + virtual void parseLinkageSpecification(LinkageSpecificationAST*); + virtual void parseNamespace(NamespaceAST*); + virtual void parseNamespaceAlias(NamespaceAliasAST*); + virtual void parseUsing(UsingAST*); + virtual void parseUsingDirective(UsingDirectiveAST*); + virtual void parseTypedef(TypedefAST*); + virtual void parseTemplateDeclaration(TemplateDeclarationAST*); + virtual void parseSimpleDeclaration(SimpleDeclarationAST*); + virtual void parseFunctionDefinition(FunctionDefinitionAST*); + virtual void parseLinkageBody(LinkageBodyAST*); + virtual void parseAccessDeclaration(AccessDeclarationAST*); + + // type-specifier + virtual void parseTypeSpecifier(TypeSpecifierAST*); + virtual void parseClassSpecifier(ClassSpecifierAST*); + virtual void parseEnumSpecifier(EnumSpecifierAST*); + virtual void parseElaboratedTypeSpecifier(ElaboratedTypeSpecifierAST*); + +private: + TreeParser(const TreeParser& source); + void operator = (const TreeParser& source); +}; + +#endif // __tree_parser_h diff -Nru umbrello-4.12.3/lib/interfaces/codemodel.cpp umbrello-4.12.90/lib/interfaces/codemodel.cpp --- umbrello-4.12.3/lib/interfaces/codemodel.cpp 1970-01-01 00:00:00.000000000 +0000 +++ umbrello-4.12.90/lib/interfaces/codemodel.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -0,0 +1,1866 @@ +/* This file is part of KDevelop + Copyright (C) 2003 Roberto Raggi + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include "codemodel.h" +#include "driver.h" +#include +#include + +///Little helper-functions to save a lot of typing and possible errors +template +bool eachCanUpdate(const MapContainer& old, const MapContainer& newMap) +{ + if (old.size() != newMap.size()) return false; + + typename MapContainer::const_iterator oldIt = old.begin(); + typename MapContainer::const_iterator newIt = newMap.begin(); + while (oldIt != old.end()) { + typedef typename MapContainer::mapped_type ListType; + if ((*oldIt).size() != (*newIt).size()) return false; + typename ListType::const_iterator it1 = (*oldIt).begin(); + typename ListType::const_iterator it2 = (*newIt).begin(); + + while (it1 != (*oldIt).end()) { + if (!(*it1)->canUpdate(*it2)) return false; + ++it1; + ++it2; + } + ++oldIt; + ++newIt; + } + return true; +} + +template +void eachUpdate(MapContainer& old, const MapContainer& newMap) +{ + if (old.size() != newMap.size()) kdError(9007) << "error in eachUpdate(...) 1" << endl; + typename MapContainer::iterator oldIt = old.begin(); + typename MapContainer::const_iterator newIt = newMap.begin(); + while (oldIt != old.end()) { + if ((*oldIt).size() != (*newIt).size()) kdError(9007) << "error in eachUpdate(...) 2" << endl; + typedef typename MapContainer::mapped_type ListType; + typename ListType::iterator it1 = (*oldIt).begin(); + typename ListType::const_iterator it2 = (*newIt).begin(); + while (it1 != (*oldIt).end()) { + (*it1)->update(*it2); + ++it1; + ++it2; + } + ++oldIt; + ++newIt; + } +} + +///Versions for contains that do not contain maps again +template +bool eachCanUpdateSingle(const MapContainer& old, const MapContainer& newMap) +{ + if (old.size() != newMap.size()) return false; + + typename MapContainer::const_iterator oldIt = old.begin(); + typename MapContainer::const_iterator newIt = newMap.begin(); + while (oldIt != old.end()) { + if (!(*oldIt)->canUpdate(*newIt)) return false; + ++oldIt; + ++newIt; + } + return true; +} + +template +void eachUpdateSingle(MapContainer& old, const MapContainer& newMap) +{ + if (old.size() != newMap.size()) kdError(9007) << "error in eachUpdate(...) 1" << endl; + typename MapContainer::iterator oldIt = old.begin(); + typename MapContainer::const_iterator newIt = newMap.begin(); + while (oldIt != old.end()) { + (*oldIt)->update(*newIt); + ++oldIt; + ++newIt; + } +} + +CodeModel::CodeModel() +{ + wipeout(); + m_currentGroupId = 1; ///0 stands for invalid group +} + +CodeModel::~ CodeModel() +{ +} + +int CodeModel::newGroupId() +{ + return (m_currentGroupId++) * 2; +} + +inline bool isSingleGroup(const int group) +{ + return (group % 2) == 0; +} + +QStringList CodeModel::getGroupStrings(int gid) const +{ + QStringList ret; + for (QMap::ConstIterator it = m_files.begin(); it != m_files.end(); ++it) { + if ((*it)->groupId() == gid) ret.append((*it)-> name()); + } + return ret; +} + + +FileList CodeModel::getGroup(int gid) const +{ + FileList ret; + for (QMap::ConstIterator it = m_files.begin(); it != m_files.end(); ++it) { + if ((*it)->groupId() == gid) ret.append(*it); + } + return ret; +} + +FileList CodeModel::getGroup(const FileDom& dom) const +{ + return getGroup(dom->groupId()); +} + +int CodeModel::mergeGroups(int g1, int g2) +{ + if (!g1 || !g2) return 0; + if (g1 == g2) return g1; + int ng = isSingleGroup(g1) ? g2 : g1; + if (isSingleGroup(ng)) + ng = newGroupId() + 1; + + for (QMap::iterator it = m_files.begin(); it != m_files.end(); ++it) { + if ((*it)->groupId() == g2 || (*it)->groupId() == g1) (*it)->setGroupId(ng); + } + return ng; +} + +template static void dumpMap(std::ostream& file, QMap& map) +{ + typename QMap::Iterator it = map.begin(); + for (; it != map.end(); ++it) { + typename Type::Iterator it2 = (*it).begin(); + for (; it2 != (*it).end(); ++it2) { + (*it2) -> dump(file, true); + } + } +} + +template static void dumpMapDirect(std::ostream& file, QMap& map) +{ + typename QMap::Iterator it = map.begin(); + for (; it != map.end(); ++it) { + (*it) -> dump(file, true); + } +} + +void CodeModelItem::dump(std::ostream& file, bool recurse, QString Info) +{ + ostringstream str(ostringstream::out); + + str << "name: " << name().ascii() << "\n"; + str << "kind: " << m_kind << " "; + + if (isFile()) str << "isFile "; + if (isNamespace()) str << "isNamespace "; + if (isClass()) str << "isClass "; + if (isFunction()) str << "isFunction "; + if (isFunctionDefinition()) str << "isFunctionDefinition "; + if (isVariable()) str << "isVariable "; + if (isArgument()) str << "isArgument "; + if (isEnum()) str << "isEnum "; + if (isEnumerator()) str << "isEnumerator "; + if (isTypeAlias()) str << "isTypeAlias "; + if (isCustom()) str << "isCustom "; + str << "\n"; + str << "File: " << fileName().ascii() << " "; + int line, col; + getStartPosition(&line, &col); + str << "s:(" << line << ", " << col << ") "; + getEndPosition(&line, &col); + str << "e:(" << line << ", " << col << ")\n"; + + + Info.prepend(str.str().c_str()); + + file << Info.ascii() << "\n"; + if (recurse) {} ///just to get rid of the warning +} + +void ClassModel::dump(std::ostream& file, bool recurse, QString Info) +{ + ostringstream str(ostringstream::out); + + + str << "scope: " << m_scope.join("::").ascii() << "\n"; + str << "bases: " << m_baseClassList.join(" ").ascii() << "\n"; + + Info.prepend(str.str().c_str()); + + CodeModelItem::dump(file, false, Info); + + if (recurse) { + dumpMap(file, m_classes); + } +} + +void NamespaceAliasModel::read(QDataStream& stream) +{ + QString tempFileName; + stream >> m_name >> m_aliasName >> tempFileName; + m_fileName = HashedString(tempFileName); +} + +void NamespaceAliasModel::write(QDataStream& stream) const +{ + stream << m_name << m_aliasName << m_fileName.str(); +} + +void NamespaceImportModel::read(QDataStream& stream) +{ + QString tempFileName; + stream >> m_name >> tempFileName; + m_fileName = HashedString(tempFileName); +} + +void NamespaceImportModel::write(QDataStream& stream) const +{ + stream << m_name << m_fileName.str(); +} + +void NamespaceModel::dump(std::ostream& file, bool recurse, QString Info) +{ + ostringstream str(ostringstream::out); + + Info.prepend(str.str().c_str()); + + ClassModel::dump(file, false, Info); + + if (recurse) { + dumpMapDirect(file, m_namespaces); + } +} + +void ArgumentModel::dump(std::ostream& file, bool recurse, QString Info) +{ + ostringstream str(ostringstream::out); + + str << "type: " << m_type.ascii() << " default: " << m_defaultValue.ascii() << "\n"; + + Info.prepend(str.str().c_str()); + + CodeModelItem::dump(file, false, Info); + + if (recurse) {} ///just to get rid of the warning +} + +void FunctionModel::dump(std::ostream& file, bool recurse, QString Info) +{ + ostringstream str(ostringstream::out); + + str << "access: " << m_access; + + str << " scope: " << m_scope.join("::").ascii() << "\n"; + + if (isAbstract()) str << "isAbstract "; + if (isConstant()) str << "isConstant "; + if (isFunction()) str << "isFunction "; + if (isInline()) str << "isInline "; + if (isSignal()) str << "isSignal "; + if (isSlot()) str << "isSlot "; + if (isStatic()) str << "isStatic "; + if (isVirtual()) str << "isVirtual "; + + str << "\n"; + str << "result-type: " << resultType().ascii() << "\n"; + + Info.prepend(str.str().c_str()); + + CodeModelItem::dump(file, false, Info); + + if (recurse) { + for (ArgumentList::iterator it = m_arguments.begin(); it != m_arguments.end(); ++it) { + (*it) -> dump(file, true); + } + } +} + +void VariableModel::dump(std::ostream& file, bool recurse, QString Info) +{ + ostringstream str(ostringstream::out); + + str << "access: " << m_access << "type: " << m_type.ascii() << "\n"; + + if (isStatic()) str << "isStatic "; + + str << "\n"; + + Info.prepend(str.str().c_str()); + + CodeModelItem::dump(file, false, Info); + + if (recurse) {} ///just to get rid of the warning +} + +void CodeModel::dump(std::ostream& file, QString Info) +{ + ostringstream str(ostringstream::out); + + Info.prepend(str.str().c_str()); + + file << Info.ascii() << "\n"; + + QMap::iterator it = m_files.begin(); + for (; it != m_files.end(); ++it) { + (*it) -> dump(file, true); + } +} + +void EnumModel::dump(std::ostream& file, bool recurse, QString Info) +{ + ostringstream str(ostringstream::out); + + str << "access: " << m_access << "\n"; + + Info.prepend(str.str().c_str()); + + CodeModelItem::dump(file, false, Info); + + if (recurse) { + dumpMapDirect(file, m_enumerators); + } +} + +void EnumeratorModel::dump(std::ostream& file, bool recurse, QString Info) +{ + ostringstream str(ostringstream::out); + + str << "value: " << m_value.ascii() << "\n"; + + Info.prepend(str.str().c_str()); + + CodeModelItem::dump(file, false, Info); + + if (recurse) {} ///just to get rid of the warning +} + +void TypeAliasModel::dump(std::ostream& file, bool recurse, QString Info) +{ + ostringstream str(ostringstream::out); + + str << "type: " << m_type.ascii() << "\n"; + + Info.prepend(str.str().c_str()); + + CodeModelItem::dump(file, false, Info); + + if (recurse) {} ///just to get rid of the warning +} + +void CodeModel::wipeout() +{ + m_files.clear(); + NamespaceDom ns = create(); + ns->setName("::"); + + m_globalNamespace = ns; +} + +FileList CodeModel::fileList() +{ + return m_files.values(); +} + +const FileList CodeModel::fileList() const +{ + return m_files.values(); +} + +bool CodeModel::hasFile(const QString & name) const +{ + return m_files.contains(name); +} + +FileDom CodeModel::fileByName(const QString & name) +{ + QMap::const_iterator it = m_files.find(name); + if (it != m_files.end()) { + return *it; + } else { + return FileDom(); + } +} + +const FileDom CodeModel::fileByName(const QString & name) const +{ + QMap::const_iterator it = m_files.find(name); + if (it != m_files.end()) { + return *it; + } else { + return FileDom(); + } +} + +void CodeModel::addNamespace(NamespaceDom target, NamespaceDom source) +{ + if (source->name().isEmpty()) { + return; + } else if (!target->hasNamespace(source->name())) { + NamespaceDom ns = this->create(); + ns->setName(source->name()); + ns->setFileName(source->fileName()); /// \FIXME ROBE + ns->setScope(source->scope()); + target->addNamespace(ns); + } + + NamespaceDom ns = target->namespaceByName(source->name()); + + NamespaceList namespaceList = source->namespaceList(); + ClassList classList = source->classList(); + FunctionList functionList = source->functionList(); + FunctionDefinitionList functionDefinitionList = source->functionDefinitionList(); + VariableList variableList = source->variableList(); + EnumList enumList = source->enumList(); + TypeAliasList typeAliasList = source->typeAliasList(); + const NamespaceModel::NamespaceAliasModelList& namespaceAliases = source->namespaceAliases(); + const NamespaceModel::NamespaceImportModelList& namespaceImports = source->namespaceImports(); + + for (NamespaceList::Iterator it=namespaceList.begin(); it!=namespaceList.end(); ++it) + addNamespace(ns, *it); + for (ClassList::Iterator it=classList.begin(); it!=classList.end(); ++it) + ns->addClass(*it); + for (FunctionList::Iterator it=functionList.begin(); it!=functionList.end(); ++it) + ns->addFunction(*it); + for (FunctionDefinitionList::Iterator it=functionDefinitionList.begin(); it!=functionDefinitionList.end(); ++it) + ns->addFunctionDefinition(*it); + for (VariableList::Iterator it=variableList.begin(); it!=variableList.end(); ++it) + ns->addVariable(*it); + for (EnumList::Iterator it=enumList.begin(); it!=enumList.end(); ++it) + ns->addEnum(*it); + for (TypeAliasList::Iterator it=typeAliasList.begin(); it!=typeAliasList.end(); ++it) + ns->addTypeAlias(*it); + for (NamespaceModel::NamespaceAliasModelList::const_iterator it=namespaceAliases.begin(); it != namespaceAliases.end(); ++it) + ns->addNamespaceAlias(*it); + for (NamespaceModel::NamespaceImportModelList::const_iterator it=namespaceImports.begin(); it != namespaceImports.end(); ++it) + ns->addNamespaceImport(*it); +} + +void CodeModel::removeNamespace(NamespaceDom target, NamespaceDom source) +{ + if (source->name().isEmpty() || !target->hasNamespace(source->name())) + return; + + NamespaceDom ns = target->namespaceByName(source->name()); + + NamespaceList namespaceList = source->namespaceList(); + ClassList classList = source->classList(); + FunctionList functionList = source->functionList(); + FunctionDefinitionList functionDefinitionList = source->functionDefinitionList(); + VariableList variableList = source->variableList(); + EnumList enumList = source->enumList(); + TypeAliasList typeAliasList = source->typeAliasList(); + const NamespaceModel::NamespaceAliasModelList& namespaceAliases = source->namespaceAliases(); + const NamespaceModel::NamespaceImportModelList& namespaceImports = source->namespaceImports(); + + for (NamespaceList::Iterator it=namespaceList.begin(); it!=namespaceList.end(); ++it) + removeNamespace(ns, *it); + for (ClassList::Iterator it=classList.begin(); it!=classList.end(); ++it) + ns->removeClass(*it); + for (FunctionList::Iterator it=functionList.begin(); it!=functionList.end(); ++it) + ns->removeFunction(*it); + for (FunctionDefinitionList::Iterator it=functionDefinitionList.begin(); it!=functionDefinitionList.end(); ++it) + ns->removeFunctionDefinition(*it); + for (VariableList::Iterator it=variableList.begin(); it!=variableList.end(); ++it) + ns->removeVariable(*it); + for (EnumList::Iterator it=enumList.begin(); it!=enumList.end(); ++it) + ns->removeEnum(*it); + for (TypeAliasList::Iterator it=typeAliasList.begin(); it!=typeAliasList.end(); ++it) + ns->removeTypeAlias(*it); + for (NamespaceModel::NamespaceAliasModelList::const_iterator it=namespaceAliases.begin(); it != namespaceAliases.end(); ++it) + ns->removeNamespaceAlias(*it); + for (NamespaceModel::NamespaceImportModelList::const_iterator it=namespaceImports.begin(); it != namespaceImports.end(); ++it) + ns->removeNamespaceImport(*it); + + if (ns->namespaceList().isEmpty() && + ns->classList().isEmpty() && + ns->functionList().isEmpty() && + ns->functionDefinitionList().isEmpty() && + ns->variableList().isEmpty() && + ns->enumList().isEmpty() && + ns->typeAliasList().isEmpty() && + ns->namespaceImports().empty() && + ns->namespaceAliases().empty()) { + target->removeNamespace(ns); + } +} + +bool CodeModel::addFile(FileDom file) +{ + if (file->name().isEmpty()) + return false; + + if (m_files.find(file->name()) != m_files.end()) { + ///the error-channel is set to 9007 because this problem appears with the cpp-support, so it is needed while debugging it + kdDebug(9007) << "file " << file->name() << " was added to code-model without removing it before! \n" << kdBacktrace() << endl; + removeFile(fileByName(file->name())); + } + + // update global namespace + NamespaceList namespaceList = file->namespaceList(); + ClassList classList = file->classList(); + FunctionList functionList = file->functionList(); + FunctionDefinitionList functionDefinitionList = file->functionDefinitionList(); + VariableList variableList = file->variableList(); + EnumList enumList = file->enumList(); + TypeAliasList typeAliasList = file->typeAliasList(); + const NamespaceModel::NamespaceAliasModelList& namespaceAliases = file->namespaceAliases(); + const NamespaceModel::NamespaceImportModelList& namespaceImports = file->namespaceImports(); + + for (NamespaceList::Iterator it=namespaceList.begin(); it!=namespaceList.end(); ++it) + addNamespace(m_globalNamespace, *it); + for (ClassList::Iterator it=classList.begin(); it!=classList.end(); ++it) + m_globalNamespace->addClass(*it); + for (FunctionList::Iterator it=functionList.begin(); it!=functionList.end(); ++it) + m_globalNamespace->addFunction(*it); + for (FunctionDefinitionList::Iterator it=functionDefinitionList.begin(); it!=functionDefinitionList.end(); ++it) + m_globalNamespace->addFunctionDefinition(*it); + for (VariableList::Iterator it=variableList.begin(); it!=variableList.end(); ++it) + m_globalNamespace->addVariable(*it); + for (EnumList::Iterator it=enumList.begin(); it!=enumList.end(); ++it) + m_globalNamespace->addEnum(*it); + for (TypeAliasList::Iterator it=typeAliasList.begin(); it!=typeAliasList.end(); ++it) + m_globalNamespace->addTypeAlias(*it); + for (NamespaceModel::NamespaceAliasModelList::const_iterator it=namespaceAliases.begin(); it != namespaceAliases.end(); ++it) + m_globalNamespace->addNamespaceAlias(*it); + for (NamespaceModel::NamespaceImportModelList::const_iterator it=namespaceImports.begin(); it != namespaceImports.end(); ++it) + m_globalNamespace->addNamespaceImport(*it); + + m_files.insert(file->name(), file); + return true; +} + +void CodeModel::removeFile(FileDom file) +{ + // update global namespace + NamespaceList namespaceList = file->namespaceList(); + ClassList classList = file->classList(); + FunctionList functionList = file->functionList(); + FunctionDefinitionList functionDefinitionList = file->functionDefinitionList(); + VariableList variableList = file->variableList(); + EnumList enumList = file->enumList(); + TypeAliasList typeAliasList = file->typeAliasList(); + const NamespaceModel::NamespaceAliasModelList& namespaceAliases = file->namespaceAliases(); + const NamespaceModel::NamespaceImportModelList& namespaceImports = file->namespaceImports(); + + for (NamespaceList::Iterator it=namespaceList.begin(); it!=namespaceList.end(); ++it) + removeNamespace(m_globalNamespace, *it); + for (ClassList::Iterator it=classList.begin(); it!=classList.end(); ++it) + m_globalNamespace->removeClass(*it); + for (FunctionList::Iterator it=functionList.begin(); it!=functionList.end(); ++it) + m_globalNamespace->removeFunction(*it); + for (FunctionDefinitionList::Iterator it=functionDefinitionList.begin(); it!=functionDefinitionList.end(); ++it) + m_globalNamespace->removeFunctionDefinition(*it); + for (VariableList::Iterator it=variableList.begin(); it!=variableList.end(); ++it) + m_globalNamespace->removeVariable(*it); + for (EnumList::Iterator it=enumList.begin(); it!=enumList.end(); ++it) + m_globalNamespace->removeEnum(*it); + for (TypeAliasList::Iterator it=typeAliasList.begin(); it!=typeAliasList.end(); ++it) + m_globalNamespace->removeTypeAlias(*it); + for (NamespaceModel::NamespaceAliasModelList::const_iterator it=namespaceAliases.begin(); it != namespaceAliases.end(); ++it) + m_globalNamespace->removeNamespaceAlias(*it); + for (NamespaceModel::NamespaceImportModelList::const_iterator it=namespaceImports.begin(); it != namespaceImports.end(); ++it) + m_globalNamespace->removeNamespaceImport(*it); + + m_files.remove(file->name()); +} + +// ------------------------------------------------------------------------ +CodeModelItem::CodeModelItem(int kind, CodeModel* model) + : m_kind(kind), m_model(model) +{ + //kdDebug() << "CodeModelItem::CodeModelItem()" << endl; + m_startLine = 0; + m_startColumn = 0; + m_endLine = 0; + m_endColumn = 0; +} + +CodeModelItem::~ CodeModelItem() +{ +} + +QString CodeModelItem::name() const +{ + return m_name; +} + +void CodeModelItem::setName(const QString & name) +{ + m_name = name; +} + +const FileDom CodeModelItem::file() const +{ + return m_model->fileByName(m_fileName); +} + +FileDom CodeModelItem::file() +{ + return m_model->fileByName(m_fileName); +} + +QString CodeModelItem::fileName() const +{ + return m_fileName; +} + +void CodeModelItem::setFileName(const QString& fileName) +{ + m_fileName = fileName; +} + +void CodeModelItem::getStartPosition(int * line, int * column) const +{ + if (line) *line = m_startLine; + if (column) *column = m_startColumn; +} + +void CodeModelItem::setStartPosition(int line, int column) +{ + m_startLine = line; + m_startColumn = column; +} + +void CodeModelItem::getEndPosition(int * line, int * column) const +{ + if (line) *line = m_endLine; + if (column) *column = m_endColumn; +} + +void CodeModelItem::setEndPosition(int line, int column) +{ + m_endLine = line; + m_endColumn = column; +} + +void CodeModelItem::update(const CodeModelItem* i) +{ + m_startLine = i->m_startLine; + m_startColumn = i->m_startColumn; + m_endLine = i->m_endLine; + m_endColumn = i->m_endColumn; +} + +bool CodeModelItem::canUpdate(const CodeModelItem* i) const +{ + if (i->m_kind != m_kind || i->m_name != m_name) + return false; + return true; +} + + +// ------------------------------------------------------------------------ +NamespaceModel::NamespaceModel(CodeModel* model) + : ClassModel(model) +{ + setKind(Namespace); +} + +NamespaceList NamespaceModel::namespaceList() +{ + return m_namespaces.values(); +} + +const NamespaceList NamespaceModel::namespaceList() const +{ + return m_namespaces.values(); +} + +NamespaceDom NamespaceModel::namespaceByName(const QString & name) +{ + return m_namespaces.contains(name) ? m_namespaces[ name ] : NamespaceDom(); +} + +const NamespaceDom NamespaceModel::namespaceByName(const QString & name) const +{ + return m_namespaces.contains(name) ? m_namespaces[ name ] : NamespaceDom(); +} + +bool NamespaceModel::hasNamespace(const QString & name) const +{ + return m_namespaces.contains(name); +} + +bool NamespaceModel::addNamespace(NamespaceDom ns) +{ + if (ns->name().isEmpty()) + return false; + + m_namespaces[ ns->name() ] = ns; + return true; +} + +void NamespaceModel::removeNamespace(NamespaceDom ns) +{ + m_namespaces.remove(ns->name()); +} + +// ------------------------------------------------------------------------ +FileModel::FileModel(CodeModel* model) + : NamespaceModel(model), m_groupId(model->newGroupId()), m_parseResult(0) +{ +} + +// ------------------------------------------------------------------------ +ClassModel::ClassModel(CodeModel* model) + : CodeModelItem(Class, model) +{ +} + +QStringList ClassModel::baseClassList() const +{ + return m_baseClassList; +} + +bool ClassModel::addBaseClass(const QString & baseClass) +{ + m_baseClassList.push_back(baseClass); + return true; +} + +void ClassModel::removeBaseClass(const QString & baseClass) +{ + m_baseClassList.remove(baseClass); +} + +ClassList ClassModel::classList() +{ + ClassList l; + QMap::Iterator it = m_classes.begin(); + while (it != m_classes.end()) { + l += *it; + ++it; + } + + return l; +} + +const ClassList ClassModel::classList() const +{ + ClassList l; + QMap::ConstIterator it = m_classes.begin(); + while (it != m_classes.end()) { + l += *it; + ++it; + } + + return l; +} + +bool ClassModel::hasClass(const QString & name) const +{ + return m_classes.contains(name); +} + +ClassList ClassModel::classByName(const QString & name) +{ + return m_classes.contains(name) ? m_classes[ name ] : ClassList(); +} + +const ClassList ClassModel::classByName(const QString & name) const +{ + return m_classes.contains(name) ? m_classes[ name ] : ClassList(); +} + +bool ClassModel::addClass(ClassDom klass) +{ + if (klass->name().isEmpty()) + return false; + + m_classes[ klass->name() ].push_back(klass); + return true; +} + +void ClassModel::removeClass(ClassDom klass) +{ + m_classes[ klass->name() ].remove(klass); + + if (m_classes[klass->name()].isEmpty()) + m_classes.remove(klass->name()); +} + +FunctionList ClassModel::functionList() +{ + FunctionList l; + QMap::Iterator it = m_functions.begin(); + while (it != m_functions.end()) { + l += *it; + ++it; + } + + return l; +} + +const FunctionList ClassModel::functionList() const +{ + FunctionList l; + QMap::ConstIterator it = m_functions.begin(); + while (it != m_functions.end()) { + l += *it; + ++it; + } + + return l; +} + +bool ClassModel::hasFunction(const QString & name) const +{ + return m_functions.contains(name); +} + +FunctionList ClassModel::functionByName(const QString & name) +{ + return m_functions.contains(name) ? m_functions[ name ] : FunctionList(); +} + +const FunctionList ClassModel::functionByName(const QString & name) const +{ + return m_functions.contains(name) ? m_functions[ name ] : FunctionList(); +} + +bool ClassModel::addFunction(FunctionDom fun) +{ + if (fun->name().isEmpty()) + return false; + + m_functions[ fun->name() ].push_back(fun); + return true; +} + +void ClassModel::removeFunction(FunctionDom fun) +{ + m_functions[ fun->name() ].remove(fun); + + if (m_functions[fun->name()].isEmpty()) + m_functions.remove(fun->name()); +} + +FunctionDefinitionList ClassModel::functionDefinitionList() +{ + FunctionDefinitionList l; + QMap::Iterator it = m_functionDefinitions.begin(); + while (it != m_functionDefinitions.end()) { + l += *it; + ++it; + } + + return l; +} + +const FunctionDefinitionList ClassModel::functionDefinitionList() const +{ + FunctionDefinitionList l; + QMap::ConstIterator it = m_functionDefinitions.begin(); + while (it != m_functionDefinitions.end()) { + l += *it; + ++it; + } + + return l; +} + +bool ClassModel::hasFunctionDefinition(const QString & name) const +{ + return m_functionDefinitions.contains(name); +} + +FunctionDefinitionList ClassModel::functionDefinitionByName(const QString & name) +{ + return m_functionDefinitions.contains(name) ? m_functionDefinitions[ name ] : FunctionDefinitionList(); +} + +const FunctionDefinitionList ClassModel::functionDefinitionByName(const QString & name) const +{ + return m_functionDefinitions.contains(name) ? m_functionDefinitions[ name ] : FunctionDefinitionList(); +} + +bool ClassModel::addFunctionDefinition(FunctionDefinitionDom fun) +{ + if (fun->name().isEmpty()) + return false; + + m_functionDefinitions[ fun->name() ].push_back(fun); + return true; +} + +void ClassModel::removeFunctionDefinition(FunctionDefinitionDom fun) +{ + m_functionDefinitions[ fun->name() ].remove(fun); + + if (m_functionDefinitions[fun->name()].isEmpty()) + m_functionDefinitions.remove(fun->name()); +} + +VariableList ClassModel::variableList() +{ + return m_variables.values(); +} + +const VariableList ClassModel::variableList() const +{ + return m_variables.values(); +} + +VariableDom ClassModel::variableByName(const QString & name) +{ + return m_variables.contains(name) ? m_variables[ name ] : VariableDom(); +} + +const VariableDom ClassModel::variableByName(const QString & name) const +{ + return m_variables.contains(name) ? m_variables[ name ] : VariableDom(); +} + +bool ClassModel::hasVariable(const QString & name) const +{ + return m_variables.contains(name); +} + +bool ClassModel::addVariable(VariableDom var) +{ + if (var->name().isEmpty()) + return false; + + m_variables.insert(var->name(), var); + return true; +} + +void ClassModel::removeVariable(VariableDom var) +{ + m_variables.remove(var->name()); +} + +EnumList ClassModel::enumList() +{ + return m_enumerators.values(); +} + +const EnumList ClassModel::enumList() const +{ + return m_enumerators.values(); +} + +EnumDom ClassModel::enumByName(const QString & name) +{ + return m_enumerators.contains(name) ? m_enumerators[ name ] : EnumDom(); +} + +const EnumDom ClassModel::enumByName(const QString & name) const +{ + return m_enumerators.contains(name) ? m_enumerators[ name ] : EnumDom(); +} + +bool ClassModel::hasEnum(const QString & name) const +{ + return m_enumerators.contains(name); +} + +bool ClassModel::addEnum(EnumDom e) +{ + if (e->name().isEmpty()) + return false; + + m_enumerators.insert(e->name(), e); + return true; +} + +void ClassModel::update(const ClassModel* klass) +{ + CodeModelItem::update(klass); + eachUpdate(m_classes, klass->m_classes) ; + eachUpdate(m_functions, klass->m_functions) ; + eachUpdate(m_functionDefinitions, klass->m_functionDefinitions) ; + eachUpdateSingle(m_variables, klass->m_variables) ; + eachUpdateSingle(m_enumerators, klass->m_enumerators) ; + eachUpdate(m_typeAliases, klass->m_typeAliases); +} + +bool ClassModel::canUpdate(const ClassModel* klass) const +{ + if (!CodeModelItem::canUpdate(klass)) + return false; + + return eachCanUpdate(m_classes, klass->m_classes) && + eachCanUpdate(m_functions, klass->m_functions) && + eachCanUpdate(m_functionDefinitions, klass->m_functionDefinitions) && + eachCanUpdateSingle(m_variables, klass->m_variables) && + eachCanUpdateSingle(m_enumerators, klass->m_enumerators) && + eachCanUpdate(m_typeAliases, klass->m_typeAliases); +} + +void ClassModel::removeEnum(EnumDom e) +{ + m_enumerators.remove(e->name()); +} + +TypeAliasList ClassModel::typeAliasList() +{ + TypeAliasList l; + QMap::Iterator it = m_typeAliases.begin(); + while (it != m_typeAliases.end()) { + l += *it; + ++it; + } + + return l; +} + +const TypeAliasList ClassModel::typeAliasList() const +{ + TypeAliasList l; + QMap::ConstIterator it = m_typeAliases.begin(); + while (it != m_typeAliases.end()) { + l += *it; + ++it; + } + + return l; +} + +bool ClassModel::hasTypeAlias(const QString & name) const +{ + return m_typeAliases.contains(name); +} + +TypeAliasList ClassModel::typeAliasByName(const QString & name) +{ + return m_typeAliases.contains(name) ? m_typeAliases[ name ] : TypeAliasList(); +} + +const TypeAliasList ClassModel::typeAliasByName(const QString & name) const +{ + return m_typeAliases.contains(name) ? m_typeAliases[ name ] : TypeAliasList(); +} + +bool ClassModel::addTypeAlias(TypeAliasDom typeAlias) +{ + if (typeAlias->name().isEmpty()) + return false; + + m_typeAliases[ typeAlias->name() ].push_back(typeAlias); + return true; +} + +void ClassModel::removeTypeAlias(TypeAliasDom typeAlias) +{ + m_typeAliases[ typeAlias->name() ].remove(typeAlias); + + if (m_typeAliases[typeAlias->name()].isEmpty()) + m_typeAliases.remove(typeAlias->name()); +} + + + +// ------------------------------------------------------------------------ +ArgumentModel::ArgumentModel(CodeModel* model) + : CodeModelItem(Argument, model) +{ +} + +QString ArgumentModel::type() const +{ + return m_type; +} + +void ArgumentModel::setType(const QString& type) +{ + m_type = type; +} + +QString ArgumentModel::defaultValue() const +{ + return m_defaultValue; +} + +void ArgumentModel::setDefaultValue(const QString & defaultValue) +{ + m_defaultValue = defaultValue; +} + +// ------------------------------------------------------------------------ +FunctionModel::FunctionModel(CodeModel* model) + : CodeModelItem(Function, model) +{ + m_access = Public; + d.v.m_signal = false; + d.v.m_slot = false; + d.v.m_virtual = false; + d.v.m_static = false; + d.v.m_inline = false; + d.v.m_constant = false; + d.v.m_abstract = false; +} + +bool FunctionModel::isVirtual() const +{ + return d.v.m_virtual; +} + +void FunctionModel::setVirtual(bool isVirtual) +{ + d.v.m_virtual = isVirtual; +} + +bool FunctionModel::isStatic() const +{ + return d.v.m_static; +} + +void FunctionModel::setStatic(bool isStatic) +{ + d.v.m_static = isStatic; +} + +bool FunctionModel::isInline() const +{ + return d.v.m_inline; +} + +void FunctionModel::setInline(bool isInline) +{ + d.v.m_inline = isInline; +} + +bool FunctionModel::isConstant() const +{ + return d.v.m_constant; +} + +void FunctionModel::setConstant(bool isConstant) +{ + d.v.m_constant = isConstant; +} + +bool FunctionModel::isAbstract() const +{ + return d.v.m_abstract; +} + +void FunctionModel::setAbstract(bool isAbstract) +{ + d.v.m_abstract = isAbstract; +} + +QString FunctionModel::resultType() const +{ + return m_resultType; +} + +void FunctionModel::setResultType(const QString& type) +{ + m_resultType = type; +} + +ArgumentList FunctionModel::argumentList() +{ + return m_arguments; +} + +const ArgumentList FunctionModel::argumentList() const +{ + return m_arguments; +} + +bool FunctionModel::addArgument(ArgumentDom arg) +{ + m_arguments.push_back(arg); + return true; +} + +void FunctionModel::removeArgument(ArgumentDom arg) +{ + m_arguments.remove(arg); +} + +void FunctionModel::update(const FunctionModel* i) +{ + m_access = i->m_access; + CodeModelItem::update(i); +} + +bool FunctionModel::canUpdate(const FunctionModel* i) const +{ + if (!CodeModelItem::canUpdate(i)) + return false; + if (m_resultType != i->m_resultType || m_arguments.count() != i->m_arguments.count() || m_scope != i->m_scope) + return false; + return true; +} + + +// ------------------------------------------------------------------------ +VariableModel::VariableModel(CodeModel* model) + : CodeModelItem(Variable, model) +{ + m_access = Public; + m_static = false; + m_isEnumeratorVariable = false; +} + +bool VariableModel::isStatic() const +{ + return m_static; +} + +void VariableModel::setStatic(bool isStatic) +{ + m_static = isStatic; +} + +QString VariableModel::type() const +{ + return m_type; +} + +void VariableModel::setType(const QString& type) +{ + m_type = type; +} + +bool VariableModel::isEnumeratorVariable() const +{ + return m_isEnumeratorVariable; +} + +void VariableModel::setEnumeratorVariable(bool b) +{ + m_isEnumeratorVariable = b; +} + +int FunctionModel::access() const +{ + return m_access; +} + +void FunctionModel::setAccess(int access) +{ + m_access = access; +} + +bool FunctionModel::isSignal() const +{ + return d.v.m_signal; +} + +void FunctionModel::setSignal(bool isSignal) +{ + d.v.m_signal = isSignal; +} + +bool FunctionModel::isSlot() const +{ + return d.v.m_slot; +} + +void FunctionModel::setSlot(bool isSlot) +{ + d.v.m_slot = isSlot; +} + +FunctionDefinitionModel::FunctionDefinitionModel(CodeModel* model) + : FunctionModel(model) +{ +} + +int VariableModel::access() const +{ + return m_access; +} + +void VariableModel::setAccess(int access) +{ + m_access = access; +} + +const NamespaceDom CodeModel::globalNamespace() const +{ + return m_globalNamespace; +} + +void CodeModelItem::read(QDataStream & stream) +{ + stream + >> m_kind + >> m_name + >> m_fileName + >> m_startLine + >> m_startColumn + >> m_endLine + >> m_endColumn + >> m_comment; + + if (isTemplateable()) { + TemplateModelItem* t = (TemplateModelItem*)(this); + + t->read(stream); + } +} + +void CodeModelItem::write(QDataStream & stream) const +{ + stream + << m_kind + << m_name + << m_fileName + << m_startLine + << m_startColumn + << m_endLine + << m_endColumn + << m_comment; + + if (isTemplateable()) { + TemplateModelItem* t = (TemplateModelItem*)(this); + t-> write(stream); + } +} + +void ClassModel::read(QDataStream & stream) +{ + CodeModelItem::read(stream); + + TemplateModelItem::read(stream); + + stream >> m_scope >> m_baseClassList; + + int n; + + m_classes.clear(); + stream >> n; + for (int i=0; icreate(); + klass->read(stream); + addClass(klass); + } + + m_functions.clear(); + stream >> n; + for (int i=0; icreate(); + fun->read(stream); + addFunction(fun); + } + + m_functionDefinitions.clear(); + stream >> n; + for (int i=0; icreate(); + fun->read(stream); + addFunctionDefinition(fun); + } + + m_variables.clear(); + stream >> n; + for (int i=0; icreate(); + var->read(stream); + addVariable(var); + } + + m_enumerators.clear(); + stream >> n; + for (int i=0; icreate(); + e->read(stream); + addEnum(e); + } + + m_typeAliases.clear(); + stream >> n; + for (int i=0; icreate(); + typeAlias->read(stream); + addTypeAlias(typeAlias); + } +} + +void ClassModel::write(QDataStream & stream) const +{ + CodeModelItem::write(stream); + + TemplateModelItem::write(stream); + + stream << m_scope << m_baseClassList; + + const ClassList class_list = classList(); + stream << int(class_list.size()); + for (ClassList::ConstIterator it = class_list.begin(); it!=class_list.end(); ++it) + (*it)->write(stream); + + const FunctionList function_list = functionList(); + stream << int(function_list.size()); + for (FunctionList::ConstIterator it = function_list.begin(); it!=function_list.end(); ++it) + (*it)->write(stream); + + const FunctionDefinitionList function_definition_list = functionDefinitionList(); + stream << int(function_definition_list.size()); + for (FunctionDefinitionList::ConstIterator it = function_definition_list.begin(); it!=function_definition_list.end(); ++it) + (*it)->write(stream); + + const VariableList variable_list = variableList(); + stream << int(variable_list.size()); + for (VariableList::ConstIterator it = variable_list.begin(); it!=variable_list.end(); ++it) + (*it)->write(stream); + + const EnumList enum_list = enumList(); + stream << int(enum_list.size()); + for (EnumList::ConstIterator it = enum_list.begin(); it!=enum_list.end(); ++it) + (*it)->write(stream); + + const TypeAliasList type_alias_list = typeAliasList(); + stream << int(type_alias_list.size()); + for (TypeAliasList::ConstIterator it = type_alias_list.begin(); it!=type_alias_list.end(); ++it) + (*it)->write(stream); + +} + +void NamespaceModel::read(QDataStream & stream) +{ + ClassModel::read(stream); + + int n; + + m_namespaces.clear(); + m_namespaceAliases.clear(); + m_namespaceImports.clear(); + stream >> n; + for (int i=0; icreate(); + ns->read(stream); + addNamespace(ns); + } + + stream >> n; + for (int a = 0; a < n; a++) { + NamespaceAliasModel m; + m.read(stream); + m_namespaceAliases.insert(m); + } + stream >> n; + for (int a = 0; a < n; a++) { + NamespaceImportModel m; + m.read(stream); + m_namespaceImports.insert(m); + } +} + +void NamespaceModel::addNamespaceImport(const NamespaceImportModel& import) +{ + m_namespaceImports.insert(import); +} + +void NamespaceModel::addNamespaceAlias(const NamespaceAliasModel& alias) +{ + m_namespaceAliases.insert(alias); +} + +void NamespaceModel::removeNamespaceImport(const NamespaceImportModel& import) +{ + m_namespaceImports.erase(import); +} + +void NamespaceModel::removeNamespaceAlias(const NamespaceAliasModel& alias) +{ + m_namespaceAliases.erase(alias); +} + +void NamespaceModel::write(QDataStream & stream) const +{ + ClassModel::write(stream); + + const NamespaceList namespace_list = namespaceList(); + stream << int(namespace_list.size()); + for (NamespaceList::ConstIterator it = namespace_list.begin(); it!=namespace_list.end(); ++it) + (*it)->write(stream); + + stream << int(m_namespaceAliases.size()); + for (NamespaceAliasModelList::const_iterator it = m_namespaceAliases.begin(); it != m_namespaceAliases.end(); ++it) + (*it).write(stream); + stream << int(m_namespaceImports.size()); + for (NamespaceImportModelList::const_iterator it = m_namespaceImports.begin(); it != m_namespaceImports.end(); ++it) + (*it).write(stream); +} + +bool NamespaceModel::canUpdate(const NamespaceModel* ns) const +{ + if (!ClassModel::canUpdate(ns)) + return false; + + const NamespaceAliasModelList& aliases = namespaceAliases(); + const NamespaceImportModelList& imports = namespaceImports(); + const NamespaceAliasModelList& aliases2 = ns->namespaceAliases(); + const NamespaceImportModelList& imports2 = ns->namespaceImports(); + + if (aliases.size() != aliases2.size()) return false; + if (imports.size() != imports2.size()) return false; + + ///Test if all aliases are same, if not return false + NamespaceModel::NamespaceAliasModelList::const_iterator it_al1 = aliases.begin(); + NamespaceModel::NamespaceAliasModelList::const_iterator it_al2 = aliases2.begin(); + while (it_al1 != aliases.end()) { + if (!(*it_al1 == *it_al2)) + return false; + + ++it_al1; + ++it_al2; + } + + ///Test if all imports are same, if not return false + NamespaceModel::NamespaceImportModelList::const_iterator it_ip1 = imports.begin(); + NamespaceModel::NamespaceImportModelList::const_iterator it_ip2 = imports2.begin(); + while (it_ip1 != imports.end()) { + if (!(*it_ip1 == *it_ip2)) + return false; + + ++it_ip1; + ++it_ip2; + } + + return eachCanUpdateSingle(m_namespaces, ns->m_namespaces); +} + +void NamespaceModel::update(const NamespaceModel* ns) +{ + ClassModel::update(ns); + + eachUpdateSingle(m_namespaces, ns->m_namespaces); +} + +void FileModel::read(QDataStream & stream) +{ + stream >> m_groupId; + bool b; + stream >> b; + if (b) { + int i; + stream >> i; + ParsedFileType t((ParsedFileType) i); + switch (t) { + case CppParsedFile: + m_parseResult = (AbstractParseResult*)(new ParsedFile(stream)); + break; + } + } + + NamespaceModel::read(stream); +} + +void FileModel::write(QDataStream & stream) const +{ + stream << m_groupId; + bool b = m_parseResult; + stream << b; + if (b) { + int i = m_parseResult->type(); + stream << i; + m_parseResult->write(stream); + } + + NamespaceModel::write(stream); +} + +void ArgumentModel::read(QDataStream & stream) +{ + CodeModelItem::read(stream); + + + stream >> m_type >> m_defaultValue; +} + +void ArgumentModel::write(QDataStream & stream) const +{ + CodeModelItem::write(stream); + + stream << m_type << m_defaultValue; +} + +void FunctionModel::read(QDataStream & stream) +{ + CodeModelItem::read(stream); + TemplateModelItem::read(stream); + + stream >> m_scope; + stream >> d.flags; + + int n; + + m_arguments.clear(); + stream >> n; + for (int i=0; icreate(); + arg->read(stream); + addArgument(arg); + } + + stream + >> m_resultType; +} + +void FunctionModel::write(QDataStream & stream) const +{ + CodeModelItem::write(stream); + TemplateModelItem::write(stream); + + stream << m_scope; + stream << d.flags; + + const ArgumentList argument_list = argumentList(); + stream << int(argument_list.size()); + for (ArgumentList::ConstIterator it = argument_list.begin(); it!=argument_list.end(); ++it) + (*it)->write(stream); + + stream + << m_resultType; +} + +void CodeModel::read(QDataStream & stream) +{ + int n; + + m_files.clear(); + + stream >> n; + for (int i=0; icreate(); + file->read(stream); + addFile(file); + } +} + +void CodeModel::write(QDataStream & stream) const +{ + const FileList file_list = fileList(); + stream << int(file_list.size()); + for (FileList::ConstIterator it = file_list.begin(); it!=file_list.end(); ++it) + (*it)->write(stream); +} + +void VariableModel::read(QDataStream & stream) +{ + CodeModelItem::read(stream); + stream >> m_access >> m_static >> m_type >> m_isEnumeratorVariable; +} + +void VariableModel::write(QDataStream & stream) const +{ + CodeModelItem::write(stream); + stream << m_access << m_static << m_type << m_isEnumeratorVariable; +} + +void VariableModel::update(const VariableModel* i) +{ + m_access = i->m_access; + CodeModelItem::update(i); +} + +bool VariableModel::canUpdate(const VariableModel* i) const +{ + if (!CodeModelItem::canUpdate(i)) + return false; + if (m_access != i->m_access || m_static != i->m_static || m_type != i->m_type || m_isEnumeratorVariable != i->m_isEnumeratorVariable) + return false; + return true; +} + +// ------------------------------------------------------- +EnumModel::EnumModel(CodeModel * model) + : CodeModelItem(Enum, model) +{ +} + +int EnumModel::access() const +{ + return m_access; +} + +void EnumModel::setAccess(int access) +{ + m_access = access; +} + +EnumeratorList EnumModel::enumeratorList() +{ + return m_enumerators.values(); +} + +const EnumeratorList EnumModel::enumeratorList() const +{ + return m_enumerators.values(); +} + +void EnumModel::addEnumerator(EnumeratorDom enumerator) +{ + m_enumerators.insert(enumerator->name(), enumerator); +} + +void EnumModel::read(QDataStream & stream) +{ + CodeModelItem::read(stream); + stream >> m_access; + + int n; + stream >> n; + for (int i=0; icreate(); + e->read(stream); + addEnumerator(e); + } +} + +void EnumModel::write(QDataStream & stream) const +{ + CodeModelItem::write(stream); + + stream << m_access; + const EnumeratorList enumerator_list = enumeratorList(); + stream << int(enumerator_list.size()); + for (EnumeratorList::ConstIterator it = enumerator_list.begin(); it!=enumerator_list.end(); ++it) + (*it)->write(stream); +} + +EnumeratorModel::EnumeratorModel(CodeModel * model) + : CodeModelItem(Enumerator, model) +{ +} + +QString EnumeratorModel::value() const +{ + return m_value; +} + +void EnumeratorModel::setValue(const QString & value) +{ + m_value = value; +} + +void EnumeratorModel::read(QDataStream & stream) +{ + CodeModelItem::read(stream); + stream >> m_value; +} + +void EnumeratorModel::write(QDataStream & stream) const +{ + CodeModelItem::write(stream); + stream << m_value; +} + +void EnumModel::removeEnumerator(EnumeratorDom e) +{ + m_enumerators.remove(e->name()); +} + +void EnumModel::update(const EnumModel* i) +{ + m_access = i->m_access; + CodeModelItem::update(i); +} + +bool EnumModel::canUpdate(const EnumModel* i) const +{ + if (!CodeModelItem::canUpdate(i)) + return false; + ///@todo check not complete + if (m_access != i->m_access || m_enumerators.count() != i->m_enumerators.count()) + return false; + return true; +} + +// --------------------------------------------------------------- +TypeAliasModel::TypeAliasModel(CodeModel * model) + : CodeModelItem(TypeAlias, model) +{ +} + +void TypeAliasModel::read(QDataStream & stream) +{ + CodeModelItem::read(stream); + + stream >> m_type; +} + +void TypeAliasModel::write(QDataStream & stream) const +{ + CodeModelItem::write(stream); + + stream << m_type; +} + +QString TypeAliasModel::type() const +{ + return m_type; +} + +void TypeAliasModel::setType(const QString & type) +{ + m_type = type; +} + +void TypeAliasModel::update(const TypeAliasModel* i) +{ + CodeModelItem::update(i); +} + +bool TypeAliasModel::canUpdate(const TypeAliasModel* i) const +{ + if (!CodeModelItem::canUpdate(i)) + return false; + return m_type == i->m_type; +} + +void FileModel::update(const FileModel* file) +{ + m_parseResult = file->m_parseResult; + NamespaceModel::update(file); +} + +FileList FileModel::wholeGroup() +{ + if (isSingleGroup(m_groupId)) return (FileList() << FileDom(this)); + return codeModel()->getGroup(m_groupId); +} + +QStringList FileModel::wholeGroupStrings() const +{ + if (isSingleGroup(m_groupId)) return (QStringList() << name()); + return codeModel()->getGroupStrings(m_groupId); +} + +ParseResultPointer FileModel::parseResult() const +{ + return m_parseResult; +} + +void FileModel::setParseResult(const ParseResultPointer& result) +{ + m_parseResult = result; +} diff -Nru umbrello-4.12.3/lib/interfaces/codemodel.h umbrello-4.12.90/lib/interfaces/codemodel.h --- umbrello-4.12.3/lib/interfaces/codemodel.h 1970-01-01 00:00:00.000000000 +0000 +++ umbrello-4.12.90/lib/interfaces/codemodel.h 2014-03-05 15:04:09.000000000 +0000 @@ -0,0 +1,1748 @@ +/* This file is part of KDevelop + Copyright (C) 2003 Roberto Raggi + Copyright (C) 2004 Matt Rogers + Copyright (C) 2004 Alexander Dymo + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +#ifndef CODEMODEL_H +#define CODEMODEL_H + +/** +@file codemodel.h +Code Model - a memory symbol store. +*/ + +#include "ast.h" + +#include + +#include +#include +#include +#include "hashedstring.h" + +#include +#include +#include +#include +#include + +enum ParsedFileType { + CppParsedFile +}; + +class AbstractParseResult : public KShared +{ +public: + virtual ~AbstractParseResult() {} + virtual void read(QDataStream& stream) = 0; + + virtual void write(QDataStream& stream) const = 0; + + virtual ParsedFileType type() const = 0; +}; + +typedef KSharedPtr ParseResultPointer; + +using namespace std; + +class CodeModel; +class CodeModelItem; +class FileModel; +class NamespaceModel; +class ClassModel; +class FunctionModel; +class FunctionDefinitionModel; +class VariableModel; +class ArgumentModel; +class EnumModel; +class EnumeratorModel; +class TypeAliasModel; + +/** +@class ItemDom +Safe pointer to the @ref CodeModelItem. +This is a type definition: @code typedef KSharedPtr ItemDom; @endcode +@sa KSharedPtr +*/ +typedef KSharedPtr ItemDom; + +/** +@class FileDom +Safe pointer to the @ref FileModel. +This is a type definition: @code typedef KSharedPtr FileDom; @endcode +@sa KSharedPtr +*/ +typedef KSharedPtr FileDom; + +/** +@class NamespaceDom +Safe pointer to the @ref NamespaceModel. +This is a type definition: @code typedef KSharedPtr NamespaceDom; @endcode +@sa KSharedPtr +*/ +typedef KSharedPtr NamespaceDom; + +/** +@class ClassDom +Safe pointer to the @ref ClassModel. +This is a type definition: @code typedef KSharedPtr ClassDom; @endcode +@sa KSharedPtr +*/ +typedef KSharedPtr ClassDom; + +/** +@class FunctionDom +Safe pointer to the @ref FunctionModel. +This is a type definition: @code typedef KSharedPtr FunctionDom; @endcode +@sa KSharedPtr +*/ +typedef KSharedPtr FunctionDom; + +/** +@class FunctionDefinitionDom +Safe pointer to the @ref FunctionDefinitionModel. +This is a type definition: @code typedef KSharedPtr FunctionDefinitionDom; @endcode +@sa KSharedPtr +*/ +typedef KSharedPtr FunctionDefinitionDom; + +/** +@class VariableDom +Safe pointer to the @ref VariableModel. +This is a type definition: @code typedef KSharedPtr VariableDom; @endcode +@sa KSharedPtr +*/ +typedef KSharedPtr VariableDom; + +/** +@class ArgumentDom +Safe pointer to the @ref ArgumentModel. +This is a type definition: @code typedef KSharedPtr ArgumentDom; @endcode +@sa KSharedPtr +*/ +typedef KSharedPtr ArgumentDom; + +/** +@class EnumDom +Safe pointer to the @ref EnumModel. +This is a type definition: @code typedef KSharedPtr EnumDom; @endcode +@sa KSharedPtr +*/ +typedef KSharedPtr EnumDom; + +/** +@class TypeAliasDom +Safe pointer to the @ref TypeAliasModel. +This is a type definition: @code typedef KSharedPtr TypeAliasDom; @endcode +@sa KSharedPtr +*/ +typedef KSharedPtr TypeAliasDom; + +/** +@class EnumeratorDom +Safe pointer to the @ref EnumeratorModel. +This is a type definition: @code typedef KSharedPtr EnumeratorDom; @endcode +@sa KSharedPtr +*/ +typedef KSharedPtr EnumeratorDom; + +/** +@class ItemList +The list of code model items. +This is a type definition: @code typedef QList ItemList; @endcode +@sa QList +*/ +typedef QList ItemList; + +/** +@class FileList +The list of code model files. +This is a type definition: @code typedef QList FileList; @endcode +@sa QList +*/ +typedef QList FileList; + +/** +@class NamespaceList +The list of code model namespaces. +This is a type definition: @code typedef QList NamespaceList; @endcode +@sa QList +*/ +typedef QList NamespaceList; + +/** +@class ClassList +The list of code model classes. +This is a type definition: @code typedef QList ClassList; @endcode +@sa QList +*/ +typedef QList ClassList; + +/** +@class FunctionList +The list of code model functions. +This is a type definition: @code typedef QList FunctionList; @endcode +@sa QList +*/ +typedef QList FunctionList; + +/** +@class FunctionDefinitionList +The list of code model function definitions. +This is a type definition: @code typedef QList FunctionDefinitionList; @endcode +@sa QList +*/ + +typedef QList FunctionDefinitionList; +/** +@class VariableList +The list of code model variables. +This is a type definition: @code typedef QList VariableList; @endcode +@sa QList +*/ +typedef QList VariableList; + +/** +@class ArgumentList +The list of code model arguments. +This is a type definition: @code typedef QList ArgumentList; @endcode +@sa QList +*/ +typedef QList ArgumentList; + +/** +@class EnumList +The list of code model enums. +This is a type definition: @code typedef QList EnumList; @endcode +@sa QList +*/ +typedef QList EnumList; + +/** +@class TypeAliasList +The list of code model type aliases. +This is a type definition: @code typedef QList TypeAliasList; @endcode +@sa QList +*/ +typedef QList TypeAliasList; + +/** +@class EnumeratorList +The list of code model enumerators. +This is a type definition: @code typedef QList EnumeratorList; @endcode +@sa QList +*/ +typedef QList EnumeratorList; + +/** +Iterates through @p lst and creates sorted list of code model item names. +Can be used, for example, to get the list of classes in the store: +@code +QStringList classList = sortedNameList(codeModel()->globalNamespace()->classList()); +@endcode +@param lst The list to iterate. +@return Sorted list of code model item names. +*/ +template +QStringList sortedNameList(const ItemList& lst) +{ + QStringList nameList; + + typename ItemList::ConstIterator it = lst.begin(); + while (it != lst.end()) { + if (!(*it)->name().isEmpty()) + nameList << (*it)->name(); + ++it; + } + + nameList.sort(); + return nameList; +} + +/** +Casts safe code model pointers (@p KSharedPtr objects like +FileDom, NamespaceDom, etc.) to the @p Result type. + +Example: +@code +//ns is of type NamespaceDom +ClassDom cl = model_cast(ns); +@endcode +@param x Object to cast. +*/ +template +Result model_cast(KSharedPtr x) +{ + Result r(static_cast(x)); + return r; +} + +/** +Casts code model pointers (objects like +FileModel, NamespaceModel, etc.) to the @p Result type. + +Example: +@code +//ns is of type NamespaceModel* +ClassDom cl = model_cast(ns); +@endcode +@param x Object to cast. +*/ +template +Result model_cast(T* x) +{ + Result r(static_cast(x)); + return r; +} + + +/** +Code Model - a memory symbol store. +Symbol store (aka class store) is a database of symbols +found in code with the important information about those symbols. + +For example, programming language support plugins use symbol store +to remember information about classes, functions, etc. For each type +of symbol a certain information can be stored - symbol name, the +location in source file, etc. + +@sa codemodel.h documentation for a list of typedefs and other convenience functions. + +@sa codemodel_utils.h documentation for an additional code model utility functions and classes reference. +*/ +class CodeModel +{ +public: + /**Constructor.*/ + CodeModel(); + /**Destructor.*/ + virtual ~CodeModel(); + + /**Creates a code model item. This should be used to create + code model items. + + For example, to create a class model somewhere in your plugin, use: + @code + klass = codeModel()->create(); + klass->setName("ClassName"); + klass->setFileName("FileName"); + klass->setStartPosition(line, column); + @endcode + @return Created code model item.*/ + template typename T::Ptr create() + { + typename T::Ptr ptr(new T(this)); + return ptr; + } + + /**Resets the CodeModel.*/ + void wipeout(); + + /**Gets the list of files in the store. + @return The FileList object that contains the list of files.*/ + FileList fileList(); + + /**Gets the list of files in the store. + This is a const version for convenience. + @return The FileList object that contains the list of files.*/ + const FileList fileList() const; + + /**Checks to see if a file is in the store. + @return true if @p name is in the file list.*/ + bool hasFile(const QString& name) const; + + /**Gets the FileDom object for a file. + @param name The name of the file to get the FileDom object for.*/ + FileDom fileByName(const QString& name); + + /**Gets the FileDom object for a file. + This is a const version provided for convenience. + @param name the name of the file to get the FileDom object for.*/ + const FileDom fileByName(const QString& name) const; + + /**Adds a file to the store. + @param file The FileDom object to add to the store. + @return true if the file was added successfully.*/ + bool addFile(FileDom file); + + /**Removes a file from the store. + @param file the FileDom object to remove from the store.*/ + void removeFile(FileDom file); + + /**Gets the global namespace + @return The NamespaceDom object that represents the global namespace.*/ + const NamespaceDom globalNamespace() const; + + /**Reads the model from a stream. + Use this to save the memory symbol store to a file. + + Language support plugins usually save symbols from projects before the project is + closed to avoid reparsing when the project is opened next time. + @param stream Stream to read from. + @return whether the read succeeded(may fail when the store-format is deprecated).*/ + virtual void read(QDataStream& stream); + /**Writes the model to a stream. + Use this to restore the memory symbol store to a file. + + Language support plugins usually save symbols from projects before the project is + closed to avoid reparsing when the project is opened next time. + @param stream Stream to write to.*/ + virtual void write(QDataStream& stream) const; + + /** this will dump the whole tree into dot-file-format so it can be inspected, not ready yet*/ + virtual void dump(std::ostream& file, QString Info=""); + + /** Merges two groups, by changing the group-ids of the files. + Returns the id of the new group, or 0 on fail. + @param g1 first group + @param g2 second group */ + int mergeGroups(int g1, int g2); + + /** Returns all files within the given group + it should be preferred calling FileModel::wholeGroup and + FileModel::wholeGroupStrings because those return in constant + time if they are the only member of the group */ + FileList getGroup(int gid) const; + + FileList getGroup(const FileDom& file) const; + + /** Same as above, but returns the names instead of the objects */ + virtual QStringList getGroupStrings(int gid) const; + +private: + /**Adds a namespace to the store. + @param target The NamespaceDom object that the namespace will be added to. + @param source The NamespaceDom object that contains the namespace to remove.*/ + void addNamespace(NamespaceDom target, NamespaceDom source); + + /**Removes a namespace from the store. + @param target The NamespaceDom object that the namespace will be removed from. + @param source The NamespaceDom object that contains the namespace to remove.*/ + void removeNamespace(NamespaceDom target, NamespaceDom source); + +private: + QMap m_files; + NamespaceDom m_globalNamespace; + + virtual int newGroupId(); + ///the groups were introduced to represent dependencies between different files. + ///Files can have slaves that are owned by other files within the same group. + ///While parsing, whole groups should always be parsed/reparsed together. + int m_currentGroupId; ///normally, each file has its own group. + +private: + CodeModel(const CodeModel& source); + void operator = (const CodeModel& source); + friend class CodeModelItem; + friend class FileModel; +}; + + +/** +Item in code model (symbol store). +Item is a symbol in a store. Code model provides several predefined classes +for predefined item types (files, namespaces, classes, functions and function definitions, +variables, arguments, enums and enumerators, type aliases. + +Instances of this class should be created using @ref CodeModel::create method but usually +it is better to create instances of derived classes like ClassModel, NamespaceModel, FileModel, etc. +*/ +class CodeModelItem: public KShared +{ +public: + /**A definition of safe pointer to the code model item.*/ + typedef ItemDom Ptr; + + /**A type of a code model item.*/ + enum Kind { + File, /** ParamPair; + typedef QVector< ParamPair > ParamMap; ///The first is the name, and the second the default-parameter, or "" if there is none. + + virtual ~TemplateModelItem() {} + + virtual const ParamMap& getTemplateParams() + { + return m_params; + } + + virtual void addTemplateParam(QString name, QString def = "") + { + m_params.push_back(ParamPair(name, def)); + } + + virtual void clearTemplateParams() + { + m_params.clear(); + } + + bool hasSpecializationDeclaration() const + { + return !m_specialization.isEmpty(); + } + + virtual QString getSpecializationDeclaration() const + { + return m_specialization; + } + + void setSpecializationDeclaration(const QString& str) + { + m_specialization = str; + } + + ///returns -1 if the parameter does not exist + virtual int findTemplateParam(const QString& name) const + { + for (int a = 0; a< m_params.size(); a++) + if (m_params[a].first == name) return a; + return -1; + } + + const ParamPair getParam(int index) const + { + return m_params[index]; + } + + virtual bool isTemplateable() const + { + return true; + } + + void write(QDataStream & stream) const + { + stream << m_specialization; + stream << (int)m_params.size(); + for (ParamMap::const_iterator it = m_params.begin(); it != m_params.end(); ++it) { + stream << (*it).first; + stream << (*it).second; + } + } + + void read(QDataStream & stream) + { + int count; + stream >> m_specialization; + stream >> count; + for (int a = 0; a < count; a++) { + ParamPair tmp; + stream >> tmp.first; + stream >> tmp.second; + m_params.push_back(tmp); + } + } + +protected: + ParamMap m_params; + QString m_specialization; +}; + + + +/** +Class model. +Represents a class in the code model. + +Instances of this class should be created using @ref CodeModel::create method. +*/ +class ClassModel: public CodeModelItem, public TemplateModelItem +{ +protected: + /**Constructor. + @param model Code model which stores this item.*/ + ClassModel(CodeModel* model); + +public: + /**A definition of safe pointer to the class model.*/ + typedef ClassDom Ptr; + + virtual bool isClass() const + { + return true; + } + + /**@return The scope of the class. Scope is a string list composed from names of parent classes and namespaces.*/ + QStringList scope() const + { + return m_scope; + } + /**Sets the scope of this class. + @param scope The scope - a list of parent classes and namespaces.*/ + void setScope(const QStringList& scope) + { + m_scope = scope; + } + + /**@return The list of base class names.*/ + QStringList baseClassList() const; + + /**Adds a base class to the list of base classes. + @param baseClass The base class name.*/ + bool addBaseClass(const QString& baseClass); + + /**Removes a base class from the list of base classes. + @param baseClass The base class name.*/ + void removeBaseClass(const QString& baseClass); + + /**@return The list of (sub)classes in this model.*/ + ClassList classList(); + + /**@note This is a const version provided for convenience. + @return The list of (sub)classes in this model.*/ + const ClassList classList() const; + + /**Checks if the class specified by @p name is in this model. + @param name The name of a class to look for. + @return true if the model has a class.*/ + bool hasClass(const QString& name) const; + + /**@param name The name of a class. + @return A list of classes that match the name given by @p name.*/ + ClassList classByName(const QString& name); + + /**@param name The name of a class. + @return A list of classes that match the name given by @p name. + @note This is a const version provided for convenience.*/ + const ClassList classByName(const QString& name) const; + + /**Adds a class to the model. + @param klass The class model to add. + @return true if addition was successful.*/ + bool addClass(ClassDom klass); + + /**Removes a class from the model. + @param klass The class model to remove.*/ + void removeClass(ClassDom klass); + + /**@return A list of functions in the model.*/ + FunctionList functionList(); + + /**@return A list of functions in the model. + @note This is a const version provided for convenience.*/ + const FunctionList functionList() const; + + /**Check if the function specified by @p name is in the model. + @param name The name of a function to look for. + @return true if the model has a class.*/ + bool hasFunction(const QString& name) const; + + /**@param name The name of a function to look for. + @return A list of functions that match the name given by @p name.*/ + FunctionList functionByName(const QString& name); + + /**@param name The name of a function to look for. + @return A list of functions that match the name given by @p name. + @note This is a const version provided for convenience.*/ + const FunctionList functionByName(const QString& name) const; + + /**Adds a function to the class model. + @param fun The function model to add. + @return true if addition was successful.*/ + bool addFunction(FunctionDom fun); + + /**Removes a function from the class model. + @param fun The FunctionDom object to remove from the model.*/ + void removeFunction(FunctionDom fun); + + /**@return The list of function definitions in the model.*/ + FunctionDefinitionList functionDefinitionList(); + + /**@return The list of function definitions + @note This is a const version provided for convenience.*/ + const FunctionDefinitionList functionDefinitionList() const; + + /**Checks if the function definition specified by \p name is in the model. + @param name The name of a function definition to look for. + @return true if the function definition was found.*/ + bool hasFunctionDefinition(const QString& name) const; + + /**Gets the list of functions that match the name given by \p name. + If there are no matches, then the list returned is empty. + @param name The name of a function definition to look for. + @return The FunctionDefinitionList object containing the definitions that match.*/ + FunctionDefinitionList functionDefinitionByName(const QString& name); + + /**Gets the list of functions that match the name given by \p name. + If there are no matches, then the list returned is empty. + @param name The name of a function definition to look for. + @return The FunctionDefinitionList object containing the definitions that match. + @note This is a const version provided for convenience.*/ + const FunctionDefinitionList functionDefinitionByName(const QString& name) const; + + /**Adds a function definition to the model. + @param fun The function fefinition model to add to the model. + @return true if the addition was successful.*/ + bool addFunctionDefinition(FunctionDefinitionDom fun); + + /**Removes a function definition from the model. + @param fun The function fefinition model to remove from the model.*/ + void removeFunctionDefinition(FunctionDefinitionDom fun); + + /**@return The list of variables in the model.*/ + VariableList variableList(); + + /**@return The list of variables in the model. + @note This is a const version provided for convenience.*/ + const VariableList variableList() const; + + /**Checks if the variable specified by @p name is in the model. + @param name The name of a variable. + @return true if the variable was found.*/ + bool hasVariable(const QString& name) const; + + /**Gets the variable specified by @p name. + If there are no matches, then the VariableDom object returned is empty. + @param name The name of a variable. + @return A VariableDom object that matches the name specified.*/ + VariableDom variableByName(const QString& name); + + /**Gets the variable specified by @p name. + If there are no matches, then the VariableDom object returned is empty. + @param name The name of a variable. + @return A VariableDom object that matches the name specified. + @note This is a const version provided for convenience.*/ + const VariableDom variableByName(const QString& name) const; + + /**Adds a variable to the model. + @param var The variable model to add to the model. + @return true if the addition was successful.*/ + bool addVariable(VariableDom var); + + /**Removes a variable from the model. + @param var The variable model to remove from the model.*/ + void removeVariable(VariableDom var); + + /**@return The type alias list for this model.*/ + TypeAliasList typeAliasList(); + + /**@return The type alias list for this model. + @note This is a const version provided for convenience.*/ + const TypeAliasList typeAliasList() const; + + /**Checks if the type alias specified by @p name is in the model. + @param name The name of a type alias. + @return true if the type alias was found.*/ + bool hasTypeAlias(const QString& name) const; + + /**Gets the list of type aliases that match @p name. + If there are no matches, the TypeAliasList object is empty. + @param name The name of a type alias. + @return A TypeAliasList object that contains the matches.*/ + TypeAliasList typeAliasByName(const QString& name); + + /**Gets the list of type aliases that match @p name. + If there are no matches, the TypeAliasList object is empty. + @param name The name of a type alias. + @return A TypeAliasList object that contains the matches. + @note This is a const version provided for convenience.*/ + const TypeAliasList typeAliasByName(const QString& name) const; + + /**Adds a type alias to the model. + @param typeAlias The type alias model to add to the model. + @return true if the addition was successful.*/ + bool addTypeAlias(TypeAliasDom typeAlias); + + /**Removes a type alias from the model. + @param typeAlias The TypeAliasDom object to remove from the model.*/ + void removeTypeAlias(TypeAliasDom typeAlias); + + /**@return The list of enums in the model.*/ + EnumList enumList(); + + /**@return The list of enums in the model. + @note This is a const version provided for convenience.*/ + const EnumList enumList() const; + + /**Checks if the enum specified by @p name is in the model. + @param name The name of an enum. + @return true if the enum was found.*/ + bool hasEnum(const QString& name) const; + + /**Gets the enum specified by @p name. + The EnumDom object returned will be empty if no match is found. + @param name The name of an enum. + @return The EnumDom object that contains the match.*/ + EnumDom enumByName(const QString& name); + + /**Gets the enum specified by @p name. + The EnumDom object returned will be empty if no match is found. + @param name The name of an enum. + @return The EnumDom object that contains the match.*/ + const EnumDom enumByName(const QString& name) const; + + /**Adds an enum to the model. + @param e The enum model to add to the model. + @return true if the addition was successful.*/ + bool addEnum(EnumDom e); + + /**Removes an enum from the model. + @param e The enum model to remove from the model.*/ + void removeEnum(EnumDom e); + + void update(const ClassModel* i); + bool canUpdate(const ClassModel* i) const; + + virtual void read(QDataStream& stream); + virtual void write(QDataStream& stream) const; + + virtual void dump(std::ostream& file, bool recurse=false, QString Info=""); + +private: + QStringList m_scope; + QStringList m_baseClassList; + QMap m_classes; + QMap m_functions; + QMap m_functionDefinitions; + QMap m_variables; + QMap m_typeAliases; + QMap m_enumerators; + +private: + ClassModel(const ClassModel& source); + void operator = (const ClassModel& source); + friend class CodeModel; +}; + +class NamespaceAliasModel +{ +public: + virtual ~NamespaceAliasModel() {} + + virtual void read(QDataStream& stream); + virtual void write(QDataStream& stream) const; + + QString name() const + { + return m_name; + } + + void setName(const QString& name) + { + m_name = name; + } + + void setAliasName(const QString& theValue) + { + m_aliasName = theValue; + } + + QString aliasName() const + { + return m_aliasName; + } + + void setFileName(const HashedString& theValue) + { + m_fileName = theValue; + } + + HashedString fileName() const + { + return m_fileName; + } + + bool operator < (const NamespaceAliasModel& rhs) const + { + if (m_name < rhs.m_name) return true; + if (m_name == rhs.m_name) { + if (m_aliasName < rhs.m_aliasName) return true; + if (m_aliasName == rhs.m_aliasName && m_fileName < rhs.m_fileName) return true; + } + return false; + } + + bool operator == (const NamespaceAliasModel& rhs) const + { + return m_name == rhs.m_name && m_aliasName == rhs.m_aliasName && m_fileName == rhs.m_fileName; + } + +private: + QString m_name; + QString m_aliasName; + HashedString m_fileName; +}; + +class NamespaceImportModel +{ +public: + virtual ~NamespaceImportModel() {} + virtual void read(QDataStream& stream); + virtual void write(QDataStream& stream) const; + + QString name() const + { + return m_name; + } + + HashedString fileName() const + { + return m_fileName; + } + + void setName(const QString& name) + { + m_name = name; + } + + void setFileName(const HashedString& file) + { + m_fileName = file; + } + + bool operator < (const NamespaceImportModel& rhs) const + { + if (m_name < rhs.m_name) return true; + if (m_name == rhs.m_name) + if (m_fileName < rhs.m_fileName) return true; + + return false; + } + + bool operator == (const NamespaceImportModel& rhs) const + { + return m_name == rhs.m_name && m_fileName == rhs.m_fileName; + } + +private: + QString m_name; + HashedString m_fileName; +}; + +/** +Namespace model. +Represents a namespace in the code model. +Namespace model can represent either usual c++ namespaces +and packages or modules from other languages. + +Instances of this class should be created using @ref CodeModel::create method. +*/ +class NamespaceModel: public ClassModel +{ +protected: + /**Constructor. + @param model Code model which stores this item.*/ + NamespaceModel(CodeModel* model); + +public: + typedef std::set NamespaceAliasModelList; ///I'm using std-sets here, because Qt-3 has no appropriate replacement + typedef std::set NamespaceImportModelList; + + /**A definition of safe pointer to the namespace model.*/ + typedef NamespaceDom Ptr; + + virtual bool isClass() const + { + return false; + } + virtual bool isNamespace() const + { + return true; + } + + /**@return The list of namespaces in this model.*/ + NamespaceList namespaceList(); + + /**@return The list of namespaces in this model. + @note This is a const version provided for convenience.*/ + const NamespaceList namespaceList() const; + + /**Checks if the namespace referenced by @p name is in the model. + @param name The name of a namespace. + @return true if the namespace was found.*/ + bool hasNamespace(const QString& name) const; + + /**Gets the namespace specified by @p name. + If there are no matches, then the NamespaceDom object returned is empty. + @param name The name of a namespace. + @return The NamespaceDom object that contains the match.*/ + NamespaceDom namespaceByName(const QString& name); + + /**Gets the namespace specified by @p name. + If there are no matches, then the NamespaceDom object returned is empty. + @param name The name of a namespace. + @return The NamespaceDom object that contains the match. + @note This is a const version provided for convenience.*/ + const NamespaceDom namespaceByName(const QString& name) const; + + /**Adds a namespace to the model. + @param ns The namespace model to add to the model. + @return true if addition was successful.*/ + bool addNamespace(NamespaceDom ns); + + /**Removes the namespace from the model. + @param ns The namespace model to remove from the model.*/ + void removeNamespace(NamespaceDom ns); + + /**Updates this model so it has the same content as the other one. Only the line/column is updated. canUpdate(..) must be tested before. + * @param ns the namespace to match + */ + void update(const NamespaceModel* ns); + bool canUpdate(const NamespaceModel* ns) const; + + virtual void read(QDataStream& stream); + virtual void write(QDataStream& stream) const; + + virtual void dump(std::ostream& file, bool recurse=false, QString Info=""); + + void addNamespaceImport(const NamespaceImportModel& import); + void addNamespaceAlias(const NamespaceAliasModel& alias); + void removeNamespaceImport(const NamespaceImportModel& import); + void removeNamespaceAlias(const NamespaceAliasModel& alias); + + ///Must not be called on temporary objects because a reference is returned(for performance-reasons) + const NamespaceAliasModelList& namespaceAliases() const + { + return m_namespaceAliases; + } + + ///Must not be called on temporary objects because a reference is returned(for performance-reasons) + const NamespaceImportModelList& namespaceImports() const + { + return m_namespaceImports; + } +private: + QMap m_namespaces; + NamespaceAliasModelList m_namespaceAliases; + NamespaceImportModelList m_namespaceImports; + +private: + + NamespaceModel(const NamespaceModel& source); + void operator = (const NamespaceModel& source); + friend class CodeModel; +}; + + + + +/** +File model. +Represents a file in the code model. +Files in general contain classes, namespaces, functions, +types, etc. Therefore FileModel is derived from NamespaceModel. + +Instances of this class should be created using @ref CodeModel::create method. +*/ +class FileModel: public NamespaceModel +{ +protected: + /**Constructor. + @param model Code model which stores this item.*/ + FileModel(CodeModel* model); + +public: + /**A definition of safe pointer to the file model.*/ + typedef FileDom Ptr; + + virtual bool isFile() const + { + return true; + } + + virtual int groupId() const + { + return m_groupId; + } + + virtual void setGroupId(int newId) + { + m_groupId = newId; + } + + /** This function additionally does version-checking and + should be used instead of read when read should be called + from outside. + @return whether the read was successful */ + + virtual void write(QDataStream& stream) const; + + FileList wholeGroup() ; + + QStringList wholeGroupStrings() const; + + virtual void read(QDataStream& stream); + + ParseResultPointer parseResult() const; + void setParseResult(const ParseResultPointer& result); + + void update(const FileModel* i); +private: + int m_groupId; + ParseResultPointer m_parseResult; + FileModel(const FileModel&); + void operator = (const FileModel&); + friend class CodeModel; +}; + + +/** +Function (procedure) argument model. +Represents an argument in the function. + +Instances of this class should be created using @ref CodeModel::create method. +*/ +class ArgumentModel: public CodeModelItem +{ +protected: + ArgumentModel(CodeModel* model); + +public: + /**A definition of safe pointer to the argument model.*/ + typedef ArgumentDom Ptr; + + virtual bool isArgument() const + { + return true; + } + + /**@return The type of this argument.*/ + QString type() const; + + /**Sets the type of this argument. + @param type The type to set.*/ + void setType(const QString& type); + + /**@return The default value of this argument.*/ + QString defaultValue() const; + + /**Sets the default value of this argument. + @param defaultValue The default value to set.*/ + void setDefaultValue(const QString& defaultValue); + + virtual void read(QDataStream& stream); + virtual void write(QDataStream& stream) const; + + virtual void dump(std::ostream& file, bool recurse=false, QString Info=""); + +private: + QString m_type; + QString m_defaultValue; + +private: + ArgumentModel(const ArgumentModel& source); + void operator = (const ArgumentModel& source); + friend class CodeModel; +}; + + +/** +Function model. +Represents: +- functions; +- procedures; +- class methods; +. +In languages that have separate function declarations and definitions (c++) +this represents only function declarations. @see FunctionDefinitionModel +for a model of function definitions. + +Instances of this class should be created using @ref CodeModel::create method. +*/ +class FunctionModel: public CodeModelItem, public TemplateModelItem +{ +protected: + /**Constructor. + @param model Code model which stores this item.*/ + FunctionModel(CodeModel* model); + +public: + /**A definition of safe pointer to the function model.*/ + typedef FunctionDom Ptr; + + virtual bool isFunction() const + { + return true; + } + + /**@return The scope of the function. Scope is a string list composed + from names of parent functions, classes and namespaces.*/ + QStringList scope() const + { + return m_scope; + } + + /**Sets the scope of the function. + @param scope The scope to set.*/ + void setScope(const QStringList& scope) + { + m_scope = scope; + } + + /**@return The access level of the function. Can return either values of type @ref CodeModelItem::Access or + other integers if the function has other access level (for example pascal methods can have "published" + access level).*/ + int access() const; + + /**Sets the access level of the function. + @param access The access level.*/ + void setAccess(int access); + + /**@return true if the function is a signal.*/ + bool isSignal() const; + /**Sets the function to be a signal. + @param isSignal The signal flag.*/ + void setSignal(bool isSignal); + + /**@return true if the function is a slot.*/ + bool isSlot() const; + /**Sets the function to be a slot. + @param isSlot The slot flag.*/ + void setSlot(bool isSlot); + + /**@return true if the function is a virtual function.*/ + bool isVirtual() const; + /**Sets the function to be a virtual function. + @param isVirtual The virtual flag.*/ + void setVirtual(bool isVirtual); + + /**@return true if the function is a static function.*/ + bool isStatic() const; + /**Sets the function to be a static function. + @param isStatic The static flag.*/ + void setStatic(bool isStatic); + + /**@return true if the function is an inline function.*/ + bool isInline() const; + /**Sets the function to be an inline function. + @param isInline The inline flag.*/ + void setInline(bool isInline); + + /**@return true if the function is a constant function.*/ + bool isConstant() const; + /**Sets the function to be a constant function. + @param isConstant The constant flag.*/ + void setConstant(bool isConstant); + + /**@return true if the function is an abstract function.*/ + bool isAbstract() const; + /**Sets the function to be an inline function. + @param isAbstract The abstract flag.*/ + void setAbstract(bool isAbstract); + + /**@return The result type of a function.*/ + QString resultType() const; + /**Sets the result type of a function. + @param type The type of a function result.*/ + void setResultType(const QString& type); + + /**Gets the list of arguments being passed to the function. + If there are no arguments, then the list is empty. + @return The ArgumentList object that contains the arguments for this function.*/ + ArgumentList argumentList(); + + /**Gets the list of arguments being passed to the function. + If there are no arguments, then the list is empty. + @return The ArgumentList object that contains the arguments for this function. + @note This is a const version provided for convenience.*/ + const ArgumentList argumentList() const; + + /**Adds an argument to the function. + @param arg The argument model to add as an argument to the function. + @return true if the addition was successful.*/ + bool addArgument(ArgumentDom arg); + + /**Removes an argument from the function. + @param arg The argument model to remove from the function.*/ + void removeArgument(ArgumentDom arg); + + virtual void read(QDataStream& stream); + virtual void write(QDataStream& stream) const; + + virtual void dump(std::ostream& file, bool recurse=false, QString Info=""); + + void update(const FunctionModel* i); + bool canUpdate(const FunctionModel* i) const; + +private: + QStringList m_scope; + int m_access; + + union { + struct { + int m_signal : 1; + int m_slot : 1; + int m_virtual : 1; + int m_static : 1; + int m_inline : 1; + int m_constant : 1; + int m_abstract : 1; + } v; + int flags; + } d; + + QString m_resultType; + ArgumentList m_arguments; + +private: + FunctionModel(const FunctionModel& source); + void operator = (const FunctionModel& source); + friend class CodeModel; +}; + +/** +Function model. +Represents function definition for languages that have such. + +Instances of this class should be created using @ref CodeModel::create method. +*/ +class FunctionDefinitionModel: public FunctionModel +{ +protected: + /**Constructor. + @param model Code model which stores this item.*/ + FunctionDefinitionModel(CodeModel* model); + +public: + /**A definition of safe pointer to the function definition model.*/ + typedef FunctionDefinitionDom Ptr; + + virtual bool isFunctionDefinition() const + { + return true; + } + +private: + FunctionDefinitionModel(const FunctionDefinitionModel& source); + void operator = (const FunctionDefinitionModel& source); + friend class CodeModel; +}; + + +/** +Variable model. +Represents variables and class attributes. + +Instances of this class should be created using @ref CodeModel::create method. +*/ +class VariableModel: public CodeModelItem +{ +protected: + /**Constructor. + @param model Code model which stores this item.*/ + VariableModel(CodeModel* model); + +public: + /**A definition of safe pointer to the variable model.*/ + typedef VariableDom Ptr; + + virtual bool isVariable() const + { + return true; + } + + /**@return The access level of the variable. Can return either values of type @ref CodeModelItem::Access or + other integers if the variable has other access level (for example pascal attributes can have "published" + access level).*/ + int access() const; + /**Sets the access level of the variable. + @param access The access level.*/ + void setAccess(int access); + + /**@return true if the variable is a static variable.*/ + bool isStatic() const; + /**Sets the variable to be a static variable. + @param isStatic The static flag.*/ + void setStatic(bool isStatic); + + /**@return A type of the variable.*/ + QString type() const; + /**Sets the type of the variable. + @param type The type name.*/ + void setType(const QString& type); + + /**@return If this is an enumerator, the enum it is part of, else an empty string. This is just a hack, necessary because EnumeratorModel is not used at all by the cpp-code-model. */ + bool isEnumeratorVariable() const; + + void setEnumeratorVariable(bool b); + + virtual void read(QDataStream& stream); + virtual void write(QDataStream& stream) const; + + virtual void dump(std::ostream& file, bool recurse=false, QString Info=""); + + void update(const VariableModel* i); + bool canUpdate(const VariableModel* i) const; + +private: + int m_access; + int m_static; + QString m_type; + int m_isEnumeratorVariable; + +private: + VariableModel(const VariableModel& source); + void operator = (const VariableModel& source); + friend class CodeModel; +}; + + +/** +Enum model. +Represents enums. + +Instances of this class should be created using @ref CodeModel::create method. +*/ +class EnumModel: public CodeModelItem +{ +protected: + /**Constructor. + @param model Code model which stores this item.*/ + EnumModel(CodeModel* model); + +public: + /**A definition of safe pointer to the enum model.*/ + typedef EnumDom Ptr; + + virtual bool isEnum() const + { + return true; + } + + /**@return The access level of the enum. Can return either values + of type @ref CodeModelItem::Access or other integers if the enum has other access level.*/ + int access() const; + /**Sets the access level of the enum. + @param access The access level.*/ + void setAccess(int access); + + /**@return The list of enumerators in this enum.*/ + EnumeratorList enumeratorList(); + /**@return The list of enumerators in this enum. + @note This is a const version provided for convenience.*/ + const EnumeratorList enumeratorList() const; + /**Adds an enumerator to the model. + @param e The enumerator model to add.*/ + void addEnumerator(EnumeratorDom e); + /**Removes an enumerator from the model. + @param e The enumerator model to remove.*/ + void removeEnumerator(EnumeratorDom e); + + virtual void read(QDataStream& stream); + virtual void write(QDataStream& stream) const; + + ///The dump-function is not ready yet + virtual void dump(std::ostream& file, bool recurse=false, QString Info=""); + + void update(const EnumModel* i); + bool canUpdate(const EnumModel* i) const; + +private: + int m_access; + QMap m_enumerators; + +private: + EnumModel(const EnumModel& source); + void operator = (const EnumModel& source); + friend class CodeModel; +}; + + +/** +Enumerator model. +Represents enumerators. Enums consist of enumerators, for example in code: +@code +enum Type { A, B, C}; +@endcode +Type is represented as EnumModel;\n +A, B, C are represented with EnumeratorModel. + +Instances of this class should be created using @ref CodeModel::create method. +*/ +class EnumeratorModel: public CodeModelItem +{ +protected: + /**Constructor. + @param model Code model which stores this item.*/ + EnumeratorModel(CodeModel* model); + +public: + /**A definition of safe pointer to the enumerator model.*/ + typedef EnumeratorDom Ptr; + + virtual bool isEnumerator() const + { + return true; + } + + /**@return The value of an enumerator.*/ + QString value() const; + /**Sets the value of an enumerator. + @param value The value.*/ + void setValue(const QString& value); + + virtual void read(QDataStream& stream); + virtual void write(QDataStream& stream) const; + + virtual void dump(std::ostream& file, bool recurse=false, QString Info=""); + +private: + QString m_value; + +private: + EnumeratorModel(const EnumeratorModel& source); + void operator = (const EnumeratorModel& source); + friend class CodeModel; +}; + + +/** +Type alias model. +Represents type aliases (like subtypes/derived types in Ada and typedefs in c++). +*/ +class TypeAliasModel: public CodeModelItem +{ +protected: + /**Constructor. + @param model Code model which stores this item.*/ + TypeAliasModel(CodeModel* model); + +public: + /**A definition of safe pointer to the type alias model.*/ + typedef TypeAliasDom Ptr; + + virtual bool isTypeAlias() const + { + return true; + } + + /**@return The actual type of an alias.*/ + QString type() const; + /**Sets the type of an alias. + @param type The type name.*/ + void setType(const QString& type); + + virtual void read(QDataStream& stream); + virtual void write(QDataStream& stream) const; + + + virtual void dump(std::ostream& file, bool recurse=false, QString Info=""); + + void update(const TypeAliasModel* i); + bool canUpdate(const TypeAliasModel* i) const; + +private: + QString m_type; + +private: + TypeAliasModel(const TypeAliasModel& source); + void operator = (const TypeAliasModel& source); + friend class CodeModel; +}; + +#endif diff -Nru umbrello-4.12.3/lib/interfaces/codemodel_treeparser.cpp umbrello-4.12.90/lib/interfaces/codemodel_treeparser.cpp --- umbrello-4.12.3/lib/interfaces/codemodel_treeparser.cpp 1970-01-01 00:00:00.000000000 +0000 +++ umbrello-4.12.90/lib/interfaces/codemodel_treeparser.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -0,0 +1,108 @@ +/* This file is part of KDevelop + Copyright (C) 2003 Roberto Raggi + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include "codemodel.h" +#include "codemodel_treeparser.h" + +CodeModelTreeParser::CodeModelTreeParser() +{ +} + +CodeModelTreeParser::~CodeModelTreeParser() +{ +} + +void CodeModelTreeParser::parseCode(const CodeModel * model) +{ + const FileList fileList = model->fileList(); + for (FileList::ConstIterator it=fileList.begin(); it!=fileList.end(); ++it) + parseFile(*it); +} + +void CodeModelTreeParser::parseFile(const FileModel * file) +{ + const NamespaceList namespaceList = file->namespaceList(); + const ClassList classList = file->classList(); + const FunctionList functionList = file->functionList(); + const FunctionDefinitionList functionDefinitionList = file->functionDefinitionList(); + const VariableList variableList = file->variableList(); + + for (NamespaceList::ConstIterator it=namespaceList.begin(); it!=namespaceList.end(); ++it) + parseNamespace(*it); + for (ClassList::ConstIterator it=classList.begin(); it!=classList.end(); ++it) + parseClass(*it); + for (FunctionList::ConstIterator it=functionList.begin(); it!=functionList.end(); ++it) + parseFunction(*it); + for (FunctionDefinitionList::ConstIterator it=functionDefinitionList.begin(); it!=functionDefinitionList.end(); ++it) + parseFunctionDefinition(*it); + for (VariableList::ConstIterator it=variableList.begin(); it!=variableList.end(); ++it) + parseVariable(*it); +} + +void CodeModelTreeParser::parseNamespace(const NamespaceModel * ns) +{ + const NamespaceList namespaceList = ns->namespaceList(); + const ClassList classList = ns->classList(); + const FunctionList functionList = ns->functionList(); + const FunctionDefinitionList functionDefinitionList = ns->functionDefinitionList(); + const VariableList variableList = ns->variableList(); + + for (NamespaceList::ConstIterator it=namespaceList.begin(); it!=namespaceList.end(); ++it) + parseNamespace(*it); + for (ClassList::ConstIterator it=classList.begin(); it!=classList.end(); ++it) + parseClass(*it); + for (FunctionList::ConstIterator it=functionList.begin(); it!=functionList.end(); ++it) + parseFunction(*it); + for (FunctionDefinitionList::ConstIterator it=functionDefinitionList.begin(); it!=functionDefinitionList.end(); ++it) + parseFunctionDefinition(*it); + for (VariableList::ConstIterator it=variableList.begin(); it!=variableList.end(); ++it) + parseVariable(*it); +} + +void CodeModelTreeParser::parseClass(const ClassModel * klass) +{ + const ClassList classList = klass->classList(); + const FunctionList functionList = klass->functionList(); + const FunctionDefinitionList functionDefinitionList = klass->functionDefinitionList(); + const VariableList variableList = klass->variableList(); + + for (ClassList::ConstIterator it=classList.begin(); it!=classList.end(); ++it) + parseClass(*it); + for (FunctionList::ConstIterator it=functionList.begin(); it!=functionList.end(); ++it) + parseFunction(*it); + for (FunctionDefinitionList::ConstIterator it=functionDefinitionList.begin(); it!=functionDefinitionList.end(); ++it) + parseFunctionDefinition(*it); + for (VariableList::ConstIterator it=variableList.begin(); it!=variableList.end(); ++it) + parseVariable(*it); +} + +void CodeModelTreeParser::parseFunction(const FunctionModel * /*fun*/) +{ +} + +void CodeModelTreeParser::parseFunctionDefinition(const FunctionDefinitionModel * /*fun*/) +{ +} + +void CodeModelTreeParser::parseVariable(const VariableModel * /*var*/) +{ +} + + + diff -Nru umbrello-4.12.3/lib/interfaces/codemodel_treeparser.h umbrello-4.12.90/lib/interfaces/codemodel_treeparser.h --- umbrello-4.12.3/lib/interfaces/codemodel_treeparser.h 1970-01-01 00:00:00.000000000 +0000 +++ umbrello-4.12.90/lib/interfaces/codemodel_treeparser.h 2014-03-05 15:04:09.000000000 +0000 @@ -0,0 +1,85 @@ +/* This file is part of KDevelop + Copyright (C) 2003 Roberto Raggi + Copyright (C) 2004 Alexander Dymo + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +#ifndef CODEMODEL_TREEPARSER_H +#define CODEMODEL_TREEPARSER_H + +/** +@file codemodel_treeparser.h +Tree parser for a code model. +*/ + +class FileModel; +class NamespaceModel; +class ClassModel; +class FunctionModel; +class FunctionDefinitionModel; +class VariableModel; + +/** +Tree parser for a code model. +This is a base class which can be subclassed to create a code model "tree parser". +Such tree parsers can be used to recursively walk through the whole code model +or its parts and do some actions. + +Default implementation only walks through the model and does nothing. You need +to reimplement necessary virtual methods of this class to add desired functionality. +*/ +class CodeModelTreeParser +{ +public: + /**Constructor.*/ + CodeModelTreeParser(); + /**Destructor.*/ + virtual ~CodeModelTreeParser(); + + /**Parses recursively all code in the @p model. + @param model CodeModel to parse.*/ + virtual void parseCode(const CodeModel* model); + + /**Parses recursively all code in the @p file. + @param file FileModel to parse.*/ + virtual void parseFile(const FileModel* file); + + /**Parses recursively all code in the namespace @p ns. + @param ns NamespaceModel to parse.*/ + virtual void parseNamespace(const NamespaceModel* ns); + + /**Parses recursively all code in the class @p klass. + @param klass ClassModel to parse.*/ + virtual void parseClass(const ClassModel* klass); + + /**Parses function (function declaration) @p fun. + @param fun FunctionModel to parse.*/ + virtual void parseFunction(const FunctionModel* fun); + + /**Parses function definition @p fun. + @param fun FunctionDefinitionModel to parse.*/ + virtual void parseFunctionDefinition(const FunctionDefinitionModel* fun); + + /**Parses variable @p var. + @param var VariableModel to parse.*/ + virtual void parseVariable(const VariableModel* var); + +private: + CodeModelTreeParser(const CodeModelTreeParser& source); + void operator = (const CodeModelTreeParser& source); +}; + +#endif diff -Nru umbrello-4.12.3/lib/interfaces/codemodel_utils.cpp umbrello-4.12.90/lib/interfaces/codemodel_utils.cpp --- umbrello-4.12.3/lib/interfaces/codemodel_utils.cpp 1970-01-01 00:00:00.000000000 +0000 +++ umbrello-4.12.90/lib/interfaces/codemodel_utils.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -0,0 +1,697 @@ +/* This file is part of KDevelop + Copyright (C) 2003 Roberto Raggi + Copyright (C) 2003 Alexander Dymo + Copyright (C) 2004 Jonas Jacobi + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include "codemodel_utils.h" + +namespace CodeModelUtils +{ + +namespace Functions +{ + +void processClasses(FunctionList &list, const ClassDom dom) +{ + const ClassList cllist = dom->classList(); + for (ClassList::ConstIterator it = cllist.begin(); it != cllist.end(); ++it) { + processClasses(list, *it); + } + + const FunctionList fnlist = dom->functionList(); + for (FunctionList::ConstIterator it = fnlist.begin(); it != fnlist.end(); ++it) { + list.append(*it); + } +} + +void processNamespaces(FunctionList &list, const NamespaceDom dom) +{ + const NamespaceList nslist = dom->namespaceList(); + for (NamespaceList::ConstIterator it = nslist.begin(); it != nslist.end(); ++it) { + processNamespaces(list, *it); + } + const ClassList cllist = dom->classList(); + for (ClassList::ConstIterator it = cllist.begin(); it != cllist.end(); ++it) { + processClasses(list, *it); + } + + const FunctionList fnlist = dom->functionList(); + for (FunctionList::ConstIterator it = fnlist.begin(); it != fnlist.end(); ++it) { + list.append(*it); + } +} + +void processNamespaces(FunctionList & list, const NamespaceDom dom, QMap< FunctionDom, Scope > & relations) +{ + const NamespaceList nslist = dom->namespaceList(); + for (NamespaceList::ConstIterator it = nslist.begin(); it != nslist.end(); ++it) { + processNamespaces(list, *it, relations); + } + const ClassList cllist = dom->classList(); + for (ClassList::ConstIterator it = cllist.begin(); it != cllist.end(); ++it) { + processClasses(list, *it, relations, dom); + } + + const FunctionList fnlist = dom->functionList(); + for (FunctionList::ConstIterator it = fnlist.begin(); it != fnlist.end(); ++it) { + list.append(*it); + relations[*it].ns = dom; + } +} + +void processClasses(FunctionList & list, const ClassDom dom, QMap< FunctionDom, Scope > & relations) +{ + const ClassList cllist = dom->classList(); + for (ClassList::ConstIterator it = cllist.begin(); it != cllist.end(); ++it) { + processClasses(list, *it, relations); + } + + const FunctionList fnlist = dom->functionList(); + for (FunctionList::ConstIterator it = fnlist.begin(); it != fnlist.end(); ++it) { + list.append(*it); + relations[*it].klass = dom; + } +} + +void processClasses(FunctionList & list, const ClassDom dom, QMap< FunctionDom, Scope > & relations, const NamespaceDom & nsdom) +{ + const ClassList cllist = dom->classList(); + for (ClassList::ConstIterator it = cllist.begin(); it != cllist.end(); ++it) { + processClasses(list, *it, relations, nsdom); + } + + const FunctionList fnlist = dom->functionList(); + for (FunctionList::ConstIterator it = fnlist.begin(); it != fnlist.end(); ++it) { + list.append(*it); + relations[*it].klass = dom; + relations[*it].ns = nsdom; + } +} + +} // end of Functions namespace + + + +namespace FunctionDefinitions +{ + +void processClasses(FunctionDefinitionList &list, const ClassDom dom) +{ + const ClassList cllist = dom->classList(); + for (ClassList::ConstIterator it = cllist.begin(); it != cllist.end(); ++it) { + processClasses(list, *it); + } + + const FunctionDefinitionList fnlist = dom->functionDefinitionList(); + for (FunctionDefinitionList::ConstIterator it = fnlist.begin(); it != fnlist.end(); ++it) { + list.append(*it); + } +} + +void processNamespaces(FunctionDefinitionList &list, const NamespaceDom dom) +{ + const NamespaceList nslist = dom->namespaceList(); + for (NamespaceList::ConstIterator it = nslist.begin(); it != nslist.end(); ++it) { + processNamespaces(list, *it); + } + const ClassList cllist = dom->classList(); + for (ClassList::ConstIterator it = cllist.begin(); it != cllist.end(); ++it) { + processClasses(list, *it); + } + + const FunctionDefinitionList fnlist = dom->functionDefinitionList(); + for (FunctionDefinitionList::ConstIterator it = fnlist.begin(); it != fnlist.end(); ++it) { + list.append(*it); + } +} + +void processNamespaces(FunctionDefinitionList & list, const NamespaceDom dom, QMap< FunctionDefinitionDom, Scope > & relations) +{ + const NamespaceList nslist = dom->namespaceList(); + for (NamespaceList::ConstIterator it = nslist.begin(); it != nslist.end(); ++it) { + processNamespaces(list, *it, relations); + } + const ClassList cllist = dom->classList(); + for (ClassList::ConstIterator it = cllist.begin(); it != cllist.end(); ++it) { + processClasses(list, *it, relations, dom); + } + + const FunctionDefinitionList fnlist = dom->functionDefinitionList(); + for (FunctionDefinitionList::ConstIterator it = fnlist.begin(); it != fnlist.end(); ++it) { + list.append(*it); + relations[*it].ns = dom; + } +} + +void processClasses(FunctionDefinitionList & list, const ClassDom dom, QMap< FunctionDefinitionDom, Scope > & relations) +{ + const ClassList cllist = dom->classList(); + for (ClassList::ConstIterator it = cllist.begin(); it != cllist.end(); ++it) { + processClasses(list, *it, relations); + } + + const FunctionDefinitionList fnlist = dom->functionDefinitionList(); + for (FunctionDefinitionList::ConstIterator it = fnlist.begin(); it != fnlist.end(); ++it) { + list.append(*it); + relations[*it].klass = dom; + } +} + +void processClasses(FunctionDefinitionList & list, const ClassDom dom, QMap< FunctionDefinitionDom, Scope > & relations, const NamespaceDom & nsdom) +{ + const ClassList cllist = dom->classList(); + for (ClassList::ConstIterator it = cllist.begin(); it != cllist.end(); ++it) { + processClasses(list, *it, relations, nsdom); + } + + const FunctionDefinitionList fnlist = dom->functionDefinitionList(); + for (FunctionDefinitionList::ConstIterator it = fnlist.begin(); it != fnlist.end(); ++it) { + list.append(*it); + relations[*it].klass = dom; + relations[*it].ns = nsdom; + } +} + +} // end of FunctionDefinitions namespace + + + +FunctionList allFunctions(const FileDom &dom) +{ + using namespace Functions; + FunctionList list; + + const NamespaceList nslist = dom->namespaceList(); + for (NamespaceList::ConstIterator it = nslist.begin(); it != nslist.end(); ++it) { + processNamespaces(list, *it); + } + + const ClassList cllist = dom->classList(); + for (ClassList::ConstIterator it = cllist.begin(); it != cllist.end(); ++it) { + processClasses(list, *it); + } + + const FunctionList fnlist = dom->functionList(); + for (FunctionList::ConstIterator it = fnlist.begin(); it != fnlist.end(); ++it) { + list.append(*it); + } + + return list; +} + +AllFunctions allFunctionsDetailed(const FileDom & dom) +{ + using namespace Functions; + AllFunctions list; + + const NamespaceList nslist = dom->namespaceList(); + for (NamespaceList::ConstIterator it = nslist.begin(); it != nslist.end(); ++it) { + processNamespaces(list.functionList, *it, list.relations); + } + + const ClassList cllist = dom->classList(); + for (ClassList::ConstIterator it = cllist.begin(); it != cllist.end(); ++it) { + processClasses(list.functionList, *it, list.relations); + } + + const FunctionList fnlist = dom->functionList(); + for (FunctionList::ConstIterator it = fnlist.begin(); it != fnlist.end(); ++it) { + list.functionList.append(*it); + } + + return list; +} + +AllFunctionDefinitions allFunctionDefinitionsDetailed(const FileDom & dom) +{ + using namespace FunctionDefinitions; + AllFunctionDefinitions list; + + const NamespaceList nslist = dom->namespaceList(); + for (NamespaceList::ConstIterator it = nslist.begin(); it != nslist.end(); ++it) { + processNamespaces(list.functionList, *it, list.relations); + } + + const ClassList cllist = dom->classList(); + for (ClassList::ConstIterator it = cllist.begin(); it != cllist.end(); ++it) { + processClasses(list.functionList, *it, list.relations); + } + + const FunctionDefinitionList fnlist = dom->functionDefinitionList(); + for (FunctionDefinitionList::ConstIterator it = fnlist.begin(); it != fnlist.end(); ++it) { + list.functionList.append(*it); + } + + return list; +} + + +bool resultTypesFit(const FunctionDom & dec, const FunctionDefinitionDom & def) +{ + if (!def->resultType().contains("::")) return dec->resultType() == def->resultType(); + QStringList l1 = dec->scope() + QStringList::split("::", dec->resultType()); + QStringList l2 = QStringList::split("::", def->resultType()); + + if (l1.isEmpty() || l2.isEmpty() || l1.back() != l2.back()) return false; + + while (!l1.isEmpty() && !l2.isEmpty()) { + if (l1.back() == l2.back()) { + l1.pop_back(); + l2.pop_back(); + } else { + l1.pop_back(); + } + } + + if (l2.isEmpty()) return true; + + return false; +} + + +bool compareDeclarationToDefinition(const FunctionDom & dec, const FunctionDefinitionDom & def) +{ + if (dec->scope() == def->scope() && dec->name() == def->name() && resultTypesFit(dec, def) && dec->isConstant() == def->isConstant()) { + const ArgumentList defList = def->argumentList(), decList = dec->argumentList(); + if (defList.size() != decList.size()) + return false; + + size_t n = defList.size(); + for (size_t i = 0; i < n; ++i) + if (defList[i]->type() != decList[i]->type()) + return false; + + return true; + } + return false; +} + + +bool compareDeclarationToDefinition(const FunctionDom & dec, const FunctionDefinitionDom & def, const std::set & nsImports) +{ + if (dec->name() == def->name() && resultTypesFit(dec, def) && dec->isConstant() == def->isConstant()) { + const ArgumentList defList = def->argumentList(), decList = dec->argumentList(); + if (defList.size() != decList.size()) + return false; + + size_t n = defList.size(); + for (size_t i = 0; i < n; ++i) + if (defList[i]->type() != decList[i]->type()) + return false; + + const QStringList &defScope = def->scope(), &decScope = dec->scope(); + if (defScope != decScope) { + if (defScope.size() >= decScope.size()) + return false; + + n = decScope.size(); + for (size_t i1 = 0, i2 = 0; i1 < n; ++i1) { + if (i2 >= defScope.size() || decScope[i1] != defScope[i2]) { + NamespaceImportModel model; + model.setName(decScope[i1]); + model.setFileName(def->fileName()); + if (nsImports.find(model) == nsImports.end()) + return false; + } else { + ++i2; + } + } + } + + return true; + } + return false; +} + + + +FunctionList allFunctionsExhaustive(FileDom &dom) +{ + PredAmOwner ow(dom); + FunctionList ret; + + findFunctionDeclarations(ow, dom->wholeGroup(), ret); + + return ret; +} + + +FunctionDefinitionList allFunctionDefinitionsExhaustive(FileDom &dom) +{ + PredAmOwner ow(dom); + FunctionDefinitionList ret; + + findFunctionDefinitions(ow, dom->wholeGroup(), ret); + + return ret; +} + + + +ClassDom findClassByPosition(NamespaceModel* nameSpace, int line, int col) +{ + if (nameSpace == 0) + return 0; + + NamespaceList nsList = nameSpace->namespaceList(); + for (NamespaceList::iterator i = nsList.begin(); i != nsList.end(); ++i) { + ClassDom result = findClassByPosition(*i, line, col); + if (result != 0) + return result; + } + + ClassList classes = nameSpace->classList(); + for (ClassList::iterator i = classes.begin(); i != classes.end(); ++i) { + ClassDom result = findClassByPosition(*i, line, col); + if (result != 0) + return result; + } + + return 0; +} + +ClassDom findClassByPosition(ClassModel* aClass, int line, int col) +{ + if (aClass == 0) + return 0; + + ClassList classes = aClass->classList(); + for (ClassList::iterator i = classes.begin(); i != classes.end(); ++i) { + ClassDom result = findClassByPosition(*i, line, col); + if (result != 0) + return result; + } + + int startLine, startCol; + aClass->getStartPosition(&startLine, &startCol); + + if (startLine <= line) { + int endLine, endCol; + aClass->getEndPosition(&endLine, &endCol); + if (endLine >= line) + return (aClass); + } + + return 0; +} + +int findLastMethodLine(ClassDom aClass, CodeModelItem::Access access) +{ + int point = -1; + + const FunctionList functionList = aClass->functionList(); + for (FunctionList::ConstIterator it=functionList.begin(); it!=functionList.end(); ++it) { + int funEndLine, funEndColumn; + (*it)->getEndPosition(&funEndLine, &funEndColumn); + + if ((*it)->access() == access && point < funEndLine) + point = funEndLine; + } + + return point; +} + +int findLastVariableLine(ClassDom aClass, CodeModelItem::Access access) +{ + int point = -1; + + const VariableList varList = aClass->variableList(); + for (VariableList::ConstIterator it= varList.begin(); it!= varList.end(); ++it) { + int varEndLine, varEndColumn; + (*it)->getEndPosition(&varEndLine, &varEndColumn); + + if ((*it)->access() == access && point < varEndLine) + point = varEndLine; + } + + return point; +} + +QString accessSpecifierToString(CodeModelItem::Access access) +{ + switch (access) { + case CodeModelItem::Public: + return "public"; + case CodeModelItem::Protected: + return "protected"; + case CodeModelItem::Private: + return "private"; + default: + return "unknown"; + } +} + +FunctionDefinitionDom CodeModelHelper::functionDefinitionAt(NamespaceDom ns, int line, int column) +{ + NamespaceList namespaceList = ns->namespaceList(); + NamespaceList::iterator nslEnd = namespaceList.end(); + + for (NamespaceList::iterator it=namespaceList.begin(); it!=nslEnd; ++it) { + if (FunctionDefinitionDom def = functionDefinitionAt(*it, line, column)) + return def; + } + + ClassList classList = ns->classList(); + ClassList::iterator clEnd = classList.end(); + + for (ClassList::iterator it=classList.begin(); it!=clEnd; ++it) { + if (FunctionDefinitionDom def = functionDefinitionAt(*it, line, column)) + return def; + } + + FunctionDefinitionList functionDefinitionList = ns->functionDefinitionList(); + FunctionDefinitionList::iterator fdlEnd = functionDefinitionList.end(); + + for (FunctionDefinitionList::iterator it=functionDefinitionList.begin(); + it!=fdlEnd; ++it) { + if (FunctionDefinitionDom def = functionDefinitionAt(*it, line, column)) + return def; + } + + return FunctionDefinitionDom(); +} + +FunctionDefinitionDom CodeModelHelper::functionDefinitionAt(ClassDom klass, int line, int column) +{ + ClassList classList = klass->classList(); + ClassList::iterator clEnd = classList.end(); + + for (ClassList::iterator it=classList.begin(); it!=clEnd; ++it) { + if (FunctionDefinitionDom def = functionDefinitionAt(*it, line, column)) + return def; + } + + FunctionDefinitionList functionDefinitionList = klass->functionDefinitionList(); + FunctionDefinitionList::iterator fdlEnd = functionDefinitionList.end(); + for (FunctionDefinitionList::Iterator it=functionDefinitionList.begin(); + it!=fdlEnd; ++it) { + if (FunctionDefinitionDom def = functionDefinitionAt(*it, line, column)) + return def; + } + + return FunctionDefinitionDom(); +} + +FunctionDefinitionDom CodeModelHelper::functionDefinitionAt(FunctionDefinitionDom fun, int line, int // column + ) +{ + int startLine, startColumn; + int endLine, endColumn; + + fun->getStartPosition(&startLine, &startColumn); + fun->getEndPosition(&endLine, &endColumn); + + if (!(line >= startLine && line <= endLine) || fun->fileName() != m_fileName) + return FunctionDefinitionDom(); + + /* + if (line == startLine && column < startColumn) + return FunctionDefinitionDom(); + + if (line == endLine && column > endColumn) + return FunctionDefinitionDom();*/ + + return fun; +} + + + +FunctionDom CodeModelHelper::functionDeclarationAt(NamespaceDom ns, int line, int column) +{ + NamespaceList namespaceList = ns->namespaceList(); + NamespaceList::iterator nsEnd = namespaceList.end(); + for (NamespaceList::iterator it=namespaceList.begin(); it!=nsEnd; ++it) { + if (FunctionDom def = functionDeclarationAt(*it, line, column)) + return def; + } + + ClassList classList = ns->classList(); + ClassList::iterator clEnd = classList.end(); + for (ClassList::iterator it=classList.begin(); it!=clEnd; ++it) { + if (FunctionDom def = functionDeclarationAt(*it, line, column)) + return def; + } + + FunctionList functionList = ns->functionList(); + FunctionList::iterator flEnd = functionList.end(); + for (FunctionList::iterator it=functionList.begin(); + it!=flEnd; ++it) { + if (FunctionDom def = functionDeclarationAt(*it, line, column)) + return def; + } + + return FunctionDom(); +} + +FunctionDom CodeModelHelper::functionDeclarationAt(ClassDom klass, int line, int column) +{ + ClassList classList = klass->classList(); + ClassList::iterator clEnd = classList.end(); + for (ClassList::iterator it=classList.begin(); it!=clEnd; ++it) { + if (FunctionDom def = functionDeclarationAt(*it, line, column)) + return def; + } + + FunctionList functionList = klass->functionList(); + FunctionList::iterator flEnd = functionList.end(); + for (FunctionList::Iterator it=functionList.begin(); + it!=flEnd; ++it) { + if (FunctionDom def = functionDeclarationAt(*it, line, column)) + return def; + } + + return FunctionDom(); +} + +FunctionDom CodeModelHelper::functionDeclarationAt(FunctionDom fun, int line, int // column + ) +{ + int startLine, startColumn; + int endLine, endColumn; + + fun->getStartPosition(&startLine, &startColumn); + fun->getEndPosition(&endLine, &endColumn); + + if (!(line >= startLine && line <= endLine) || fun->fileName() != m_fileName) + return FunctionDom(); + + + /* if (line == startLine && column < startColumn) + return FunctionDom(); + + if (line == endLine && column > endColumn) + return FunctionDom();*/ + + return fun; +} + + + + +ClassDom CodeModelHelper::classAt(NamespaceDom ns, int line, int column) +{ + NamespaceList namespaceList = ns->namespaceList(); + NamespaceList::iterator nsEnd = namespaceList.end(); + + for (NamespaceList::iterator it=namespaceList.begin(); it!=nsEnd; ++it) { + if (ClassDom def = classAt(*it, line, column)) + return def; + } + + ClassList classList = ns->classList(); + ClassList::iterator clEnd = classList.end(); + for (ClassList::iterator it=classList.begin(); it!=clEnd; ++it) { + if (ClassDom def = classAt(*it, line, column)) + return def; + } + + return ClassDom(); +} + +ClassDom CodeModelHelper::classAt(ClassDom klass, int line, int column) +{ + ClassList classList = klass->classList(); + ClassList::iterator clEnd = classList.end(); + for (ClassList::iterator it=classList.begin(); it!=clEnd; ++it) { + if (ClassDom def = classAt(*it, line, column)) + return def; + } + + int startLine, startColumn; + int endLine, endColumn; + + klass->getStartPosition(&startLine, &startColumn); + klass->getEndPosition(&endLine, &endColumn); + + if (!(line >= startLine && line <= endLine) || klass->fileName() != m_fileName) + return ClassDom(); + + return klass; +} + + +CodeModelHelper::CodeModelHelper(CodeModel* model, FileDom file) : m_model(model) +{ + if (!file) return; + m_files = file->wholeGroup(); + m_fileName = file->name(); +} + + +FunctionDom CodeModelHelper::functionAt(int line, int column, FunctionTypes types) +{ + if (m_files.isEmpty()) return FunctionDom(); + + + FunctionDom ret; + FileList::iterator it = m_files.begin(); + while (it != m_files.end()) { + if (types & Declaration) { + ret = functionDeclarationAt(model_cast(*it), line, column); + if (ret) return ret; + } + if (types & Definition) { + FunctionDefinitionDom r = functionDefinitionAt(model_cast(*it), line, column); + if (r) { + ret = model_cast(r); + return ret; + } + } + ++it; + } + + return ret; +} + +ClassDom CodeModelHelper::classAt(int line, int column) +{ + if (m_files.isEmpty()) return ClassDom(); + + ClassDom ret; + FileList::iterator it = m_files.begin(); + while (it != m_files.end()) { + ret = classAt(model_cast(*it), line, column); + if (ret) return ret; + ++it; + } + + return ret; +} + +}//end of namespace CodeModeUtils diff -Nru umbrello-4.12.3/lib/interfaces/codemodel_utils.h umbrello-4.12.90/lib/interfaces/codemodel_utils.h --- umbrello-4.12.3/lib/interfaces/codemodel_utils.h 1970-01-01 00:00:00.000000000 +0000 +++ umbrello-4.12.90/lib/interfaces/codemodel_utils.h 2014-03-05 15:04:09.000000000 +0000 @@ -0,0 +1,575 @@ +/* This file is part of KDevelop + Copyright (C) 2003 Roberto Raggi + Copyright (C) 2003-2004 Alexander Dymo + Copyright (C) 2004 Jonas Jacobi + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +#ifndef CODEMODEL_UTILS_H +#define CODEMODEL_UTILS_H + +#include "codemodel.h" + +/** +@file codemodel_utils.h +Utility functions and classes for the CodeModel. +*/ + +/** +@class Pred +The predicate. +Pred is not a real class, it is only a template parameter used in @ref CodeModelUtils functions. + +How to create the predicate:@n +Predicate is simply a class that have +@code bool operator() (predicateArgument) @endcode. +The return value of that operator is the result of a predicate. + +For example we want to find all function definitions with a particular name. +We can use @ref CodeModelUtils::findFunctionDefinitions functions that require +you to write a predicate for function definition DOM's. +This can be done with following code: +@code +class MyPred{ +public: + MyPred(const QString &name): m_name(name) {} + + bool operator() (const FunctionDefinitionDom &def) const + { + return def->name() == m_name; + } + +private: + QString m_name; +}; +@endcode +*/ + + +/**Namespace which contains utility functions and classes for the CodeModel.*/ +namespace CodeModelUtils +{ + +/**Finds function definitions which match given predicate in files. + +Predicate can be considered as a condition. If it is true then the function definition is +added to the result list otherwise it is skipped. +@see Pred class documentation for a detailed description on how to create and use predicates. + +@param pred Predicate which is applied to a function definition before it is returned. +@param fileList The list of files to find function definitions in. +@param lst The reference to a list of function definitions. Will be filled by this function.*/ +template void findFunctionDefinitions(Pred pred, const FileList& fileList, FunctionDefinitionList & lst); + +/**Finds function definitions which match given predicate in the namespace. + +Predicate can be considered as a condition. If it is true then the function definition is +added to the result list otherwise it is skipped. +@see Pred class documentation for a detailed description on how to create and use predicates. + +@param pred Predicate which is applied to a function definition before it is returned. +@param ns The namespace to find function definitions in. +@param lst The reference to a list of function definitions. Will be filled by this function.*/ +template void findFunctionDefinitions(Pred pred, const NamespaceDom& ns, FunctionDefinitionList & lst); + +/**Finds function definitions which match given predicate in namespaces. + +Predicate can be considered as a condition. If it is true then the function definition is +added to the result list otherwise it is skipped. +@see Pred class documentation for a detailed description on how to create and use predicates. + +@param pred Predicate which is applied to a function definition before it is returned. +@param namespaceList The list of namespaces to find function definitions in. +@param lst The reference to a list of function definitions. Will be filled by this function.*/ +template void findFunctionDefinitions(Pred pred, const NamespaceList& namespaceList, FunctionDefinitionList & lst); + +/**Finds function definitions which match given predicate in classes. + +Predicate can be considered as a condition. If it is true then the function definition is +added to the result list otherwise it is skipped. +@see Pred class documentation for a detailed description on how to create and use predicates. + +@param pred Predicate which is applied to a function definition before it is returned. +@param classList The list of classes to find function definitions in. +@param lst The reference to a list of function definitions. Will be filled by this function.*/ +template void findFunctionDefinitions(Pred pred, const ClassList& classList, FunctionDefinitionList & lst); + +/**Finds function definitions which match given predicate in the list of function definitions. + +Predicate can be considered as a condition. If it is true then the function definition is +added to the result list otherwise it is skipped. +@see Pred class documentation for a detailed description on how to create and use predicates. + +@param pred Predicate which is applied to a function definition before it is returned. +@param functionDefinitionList The list of function definitions to find function definitions in. +@param lst The reference to a list of function definitions. Will be filled by this function.*/ +template void findFunctionDefinitions(Pred pred, const FunctionDefinitionList& functionDefinitionList, FunctionDefinitionList & lst); + +/**Finds function definitions which match given predicate in the class. + +Predicate can be considered as a condition. If it is true then the function definition is +added to the result list otherwise it is skipped. +@see Pred class documentation for a detailed description on how to create and use predicates. + +@param pred Predicate which is applied to a function definition before it is returned. +@param klass The class to find function definitions in. +@param lst The reference to a list of function definitions. Will be filled by this function.*/ +template void findFunctionDefinitions(Pred pred, const ClassDom& klass, FunctionDefinitionList & lst); + +/**Applies a predicate to a function definition. + +Predicate can be considered as a condition. If it is true then the function definition is +added to the result list otherwise it is skipped. +@see Pred class documentation for a detailed description on how to create and use predicates. + +@param pred Predicate which is applied to a function definition before it is returned. +@param fun The function definition. +@param lst The reference to a list of function definitions. Will be filled by this function.*/ +template void findFunctionDefinitions(Pred pred, const FunctionDefinitionDom& fun, FunctionDefinitionList & lst); + +/**Finds function declarations which match given predicate in files. + +Predicate can be considered as a condition. If it is true then the function declaration is +added to the result list otherwise it is skipped. +@see Pred class documentation for a detailed description on how to create and use predicates. + +@param pred Predicate which is applied to a function declaration before it is returned. +@param fileList The list of files to find function declarations in. +@param lst The reference to a list of function declarations. Will be filled by this function.*/ +template void findFunctionDeclarations(Pred pred, const FileList& fileList, FunctionList & lst); + +/**Finds function declarations which match given predicate in the namespace. + +Predicate can be considered as a condition. If it is true then the function declaration is +added to the result list otherwise it is skipped. +@see Pred class documentation for a detailed description on how to create and use predicates. + +@param pred Predicate which is applied to a function declaration before it is returned. +@param ns The namespace to find function declarations in. +@param lst The reference to a list of function declarations. Will be filled by this function.*/ +template void findFunctionDeclarations(Pred pred, const NamespaceDom& ns, FunctionList & lst); + +/**Finds function declarations which match given predicate in namespaces. + +Predicate can be considered as a condition. If it is true then the function declaration is +added to the result list otherwise it is skipped. +@see Pred class documentation for a detailed description on how to create and use predicates. + +@param pred Predicate which is applied to a function declaration before it is returned. +@param namespaceList The list of namespaces to find function declarations in. +@param lst The reference to a list of function declarations. Will be filled by this function.*/ +template void findFunctionDeclarations(Pred pred, const NamespaceList& namespaceList, FunctionList & lst); + +/**Finds function declarations which match given predicate in classes. + +Predicate can be considered as a condition. If it is true then the function declaration is +added to the result list otherwise it is skipped. +@see Pred class documentation for a detailed description on how to create and use predicates. + +@param pred Predicate which is applied to a function declaration before it is returned. +@param classList The list of classes to find function declarations in. +@param lst The reference to a list of function declarations. Will be filled by this function.*/ +template void findFunctionDeclarations(Pred pred, const ClassList& classList, FunctionList & lst); + +/**Finds function declarations which match given predicate in the list of function declarations. + +Predicate can be considered as a condition. If it is true then the function declaration is +added to the result list otherwise it is skipped. +@see Pred class documentation for a detailed description on how to create and use predicates. + +@param pred Predicate which is applied to a function declaration before it is returned. +@param functionList The list of function declarations to find function declarations in. +@param lst The reference to a list of function declarations. Will be filled by this function.*/ +template void findFunctionDeclarations(Pred pred, const FunctionList& functionList, FunctionList & lst); + +/**Finds function declarations which match given predicate in the class. + +Predicate can be considered as a condition. If it is true then the function declaration is +added to the result list otherwise it is skipped. +@see Pred class documentation for a detailed description on how to create and use predicates. + +@param pred Predicate which is applied to a function declaration before it is returned. +@param klass The class to find function declarations in. +@param lst The reference to a list of function declarations. Will be filled by this function.*/ +template void findFunctionDeclarations(Pred pred, const ClassDom& klass, FunctionList & lst); + +/**Applies a predicate to a function declaration. + +Predicate can be considered as a condition. If it is true then the function declaration is +added to the result list otherwise it is skipped. +@see Pred class documentation for a detailed description on how to create and use predicates. + +@param pred Predicate which is applied to a function declaration before it is returned. +@param fun The function declaration. +@param lst The reference to a list of function declarations. Will be filled by this function.*/ +template void findFunctionDeclarations(Pred pred, const FunctionDom& fun, FunctionList & lst); + + +//implementations of function templates defined above: + +template +void findFunctionDefinitions(Pred pred, const FileList& fileList, FunctionDefinitionList & lst) +{ + for (FileList::ConstIterator it=fileList.begin(); it!=fileList.end(); ++it) + findFunctionDefinitions(pred, model_cast(*it), lst); +} + +template +void findFunctionDefinitions(Pred pred, const NamespaceDom& ns, FunctionDefinitionList & lst) +{ + findFunctionDefinitions(pred, ns->namespaceList(), lst); + findFunctionDefinitions(pred, ns->classList(), lst); + findFunctionDefinitions(pred, ns->functionDefinitionList(), lst); +} + +template +void findFunctionDefinitions(Pred pred, const NamespaceList& namespaceList, FunctionDefinitionList & lst) +{ + for (NamespaceList::ConstIterator it=namespaceList.begin(); it!=namespaceList.end(); ++it) + findFunctionDefinitions(pred, *it, lst); +} + +template +void findFunctionDefinitions(Pred pred, const ClassList& classList, FunctionDefinitionList & lst) +{ + for (ClassList::ConstIterator it=classList.begin(); it!=classList.end(); ++it) + findFunctionDefinitions(pred, *it, lst); +} + +template +void findFunctionDefinitions(Pred pred, const FunctionDefinitionList& functionDefinitionList, FunctionDefinitionList & lst) +{ + for (FunctionDefinitionList::ConstIterator it=functionDefinitionList.begin(); it!=functionDefinitionList.end(); ++it) + findFunctionDefinitions(pred, *it, lst); +} + +template +void findFunctionDefinitions(Pred pred, const ClassDom& klass, FunctionDefinitionList & lst) +{ + findFunctionDefinitions(pred, klass->classList(), lst); + findFunctionDefinitions(pred, klass->functionDefinitionList(), lst); +} + +template +void findFunctionDefinitions(Pred pred, const FunctionDefinitionDom& fun, FunctionDefinitionList & lst) +{ + if (pred(fun)) + lst << fun; +} + + + +template +void findFunctionDeclarations(Pred pred, const FileList& fileList, FunctionList & lst) +{ + for (FileList::ConstIterator it=fileList.begin(); it!=fileList.end(); ++it) + findFunctionDeclarations(pred, model_cast(*it), lst); +} + +template +void findFunctionDeclarations(Pred pred, const NamespaceDom& ns, FunctionList & lst) +{ + findFunctionDeclarations(pred, ns->namespaceList(), lst); + findFunctionDeclarations(pred, ns->classList(), lst); + findFunctionDeclarations(pred, ns->functionList(), lst); +} + +template +void findFunctionDeclarations(Pred pred, const NamespaceList& namespaceList, FunctionList & lst) +{ + for (NamespaceList::ConstIterator it=namespaceList.begin(); it!=namespaceList.end(); ++it) + findFunctionDeclarations(pred, *it, lst); +} + +template +void findFunctionDeclarations(Pred pred, const ClassList& classList, FunctionList & lst) +{ + for (ClassList::ConstIterator it=classList.begin(); it!=classList.end(); ++it) + findFunctionDeclarations(pred, *it, lst); +} + +template +void findFunctionDeclarations(Pred pred, const FunctionList& functionList, FunctionList & lst) +{ + for (FunctionList::ConstIterator it=functionList.begin(); it!=functionList.end(); ++it) + findFunctionDeclarations(pred, *it, lst); +} + +template +void findFunctionDeclarations(Pred pred, const ClassDom& klass, FunctionList & lst) +{ + findFunctionDeclarations(pred, klass->classList(), lst); + findFunctionDeclarations(pred, klass->functionList(), lst); +} + +template +void findFunctionDeclarations(Pred pred, const FunctionDom& fun, FunctionList & lst) +{ + if (pred(fun)) + lst << fun; +} + +/**A scope.*/ +struct Scope { + /**Class.*/ + ClassDom klass; + /**Namespace.*/ + NamespaceDom ns; +}; + +/**Information about functions.*/ +struct AllFunctions { + /**Scope of functions.*/ + QMap relations; + /**List of functions.*/ + FunctionList functionList; +}; +/**Information about function definitions.*/ +struct AllFunctionDefinitions { + /**Scope of function definitions.*/ + QMap relations; + /**List of function definitions.*/ + FunctionDefinitionList functionList; +}; + +/**Namespace with utilities to find functions in the @ref CodeModel.*/ +namespace Functions +{ +/**Looks for functions in the class. +@param list The list of functions found by this routine. +@param dom The class to look for functions.*/ +void processClasses(FunctionList &list, const ClassDom dom); + +/**Looks for functions in the namespace. +@param list The list of functions found by this routine. +@param dom The namespace to look for functions.*/ +void processNamespaces(FunctionList &list, const NamespaceDom dom); + +/**Looks for functions in the class and also saves their scope. +@param list The list of functions found by this routine. +@param dom The class to look for functions. +@param relations The scope information.*/ +void processClasses(FunctionList &list, const ClassDom dom, QMap &relations); + +/**Looks for functions in the class and also saves their scope. +Used for classes within a namespace. +@param list The list of functions found by this routine. +@param dom The class to look for functions. +@param relations The scope information. +@param nsdom The namespace which contains a class.*/ +void processClasses(FunctionList &list, const ClassDom dom, QMap &relations, const NamespaceDom &nsdom); + +/**Looks for functions in the namespace and also saves their scope. +@param list The list of functions found by this routine. +@param dom The namespace to look for functions. +@param relations The scope information.*/ +void processNamespaces(FunctionList &list, const NamespaceDom dom, QMap &relations); +} + +/**Namespace with utilities to find function definitions in the @ref CodeModel.*/ +namespace FunctionDefinitions +{ +/**Looks for function definitions in the class. +@param list The list of function definitions found by this routine. +@param dom The class to look for function definitions.*/ +void processClasses(FunctionDefinitionList &list, const ClassDom dom); + +/**Looks for function definitions in the namespace. +@param list The list of function definitions found by this routine. +@param dom The namespace to look for function definitions.*/ +void processNamespaces(FunctionDefinitionList &list, const NamespaceDom dom); + +/**Looks for function definitions in the class and also saves their scope. +@param list The list of function definitions found by this routine. +@param dom The class to look for function definitions. +@param relations The scope information.*/ +void processClasses(FunctionDefinitionList &list, const ClassDom dom, QMap &relations); + +/**Looks for function definitions in the class and also saves their scope. +Used for classes within a namespace. +@param list The list of function definitions found by this routine. +@param dom The class to look for function definitions . +@param relations The scope information. +@param nsdom The namespace which contains a class.*/ +void processClasses(FunctionDefinitionList &list, const ClassDom dom, QMap &relations, const NamespaceDom &nsdom); + +/**Looks for function definitions in the namespace and also saves their scope. +@param list The list of function definitions found by this routine. +@param dom The namespace to look for function definitions. +@param relations The scope information.*/ +void processNamespaces(FunctionDefinitionList &list, const NamespaceDom dom, QMap &relations); +} + +/** + * Compares a declaration and a definition of a function. + * @param dec declaration + * @param def definition + * @return true, if dec is the declaration of the function definition def, false otherwise + * @author Jonas Jacobi + */ +bool compareDeclarationToDefinition(const FunctionDom& dec, const FunctionDefinitionDom& def); + +/** + * Compares a declaration and a definition of a function. + * @param dec declaration + * @param def definition + * @param nsImports namespace imports for the namespace the definition appears in + * @return true, if dec is the declaration of the function definition def, false otherwise + */ +bool compareDeclarationToDefinition(const FunctionDom& dec, const FunctionDefinitionDom& def, const std::set& nsImports); + +/** + * Predicate for use with findFunctionDefinitions. Searches for a definition matching a declaration. + * @sa Pred documentation to learn more about predicates used with code model. + * @author Jonas Jacobi + */ +class PredDefinitionMatchesDeclaration +{ +public: + PredDefinitionMatchesDeclaration(const FunctionDom& func) : m_declaration(func) {}; + bool operator() (const FunctionDefinitionDom& def) const + { + return compareDeclarationToDefinition(m_declaration, def); + } + +private: + const FunctionDom m_declaration; +}; + +template +class PredAmOwner +{ +public: + PredAmOwner(const FileDom& file) : m_file(file) {}; + bool operator() (const InputDomType& def) const + { + return def->file() == m_file; + } + +private: + const FileDom m_file; +}; + +/**@return A list of all functions in the file. +@param dom File Dom to look for functions in.*/ +FunctionList allFunctions(const FileDom &dom); +/**@return A detailed list of all functions in the file (detailed list contains +the information about a scope of each FunctionDom found). +@param dom File Dom to look for functions in.*/ +AllFunctions allFunctionsDetailed(const FileDom &dom); +/**@return A detailed list of all function definitions in the file (detailed list contains +the information about a scope of each FunctionDefinitionDom found). +@param dom File Dom to look for functions in.*/ +AllFunctionDefinitions allFunctionDefinitionsDetailed(const FileDom &dom); + +/**@return A list of all functions in the file. +This version searches the file's whole group for +functions that may have been inserted into the other file's +structure. +Unlike the methods above, this guarantees that all returned +functions physically belong to that file. +@param dom File Dom to look for functions in. */ +FunctionList allFunctionsExhaustive(FileDom &dom); + +/**@return A list of all function-definitions in the file. +This version searches the file's whole group for +functions that may have been inserted into the other file's +structure. +Unlike the methods above, this guarantees that all returned +functions physically belong to that file. +@param dom File Dom to look for functions in. */ +FunctionDefinitionList allFunctionDefinitionsExhaustive(FileDom &dom); + +/** + * Finds a class by its position in a file(position inside the part of the file, where the class is declared). + * In the case of nested classes the innermost class which is declared at/around the provided position. + * @param nameSpace A namespace to search for the class. + * @param line A linenumber inside the class declaration. + * @param col The column of line. + * @return The innermost class, which is declared at/around position defined with line / col, or 0 if no class is found. + * @author Jonas Jacobi + */ +ClassDom findClassByPosition(NamespaceModel* nameSpace, int line, int col); + +/** + * Same as above, just searches inside a class instead of a namespace. + */ +ClassDom findClassByPosition(ClassModel* aClass, int line, int col); + +/** + * Finds the last occurrence (line of file wise) of a method inside a class declaration with specific access specificer. + * This can be used e.g. to find a position to new methods to the class. + * @param aClass class to search for method. + * @param access the access specifier with which methods are searched for. + * @return The last line a Method with access specifier access is found, + * or -1 if no method with that access specifier was found. + * @author Jonas Jacobi + */ +int findLastMethodLine(ClassDom aClass, CodeModelItem::Access access); + +/** + * Same as above, but finds a membervariable instead of a method. + */ +int findLastVariableLine(ClassDom aClass, CodeModelItem::Access access); + +/** + * Get the string representation of an accesss pecifier + * @param access An access specifier to get a string representation of. + * @return string The representation of an access (e.g. "public"). + * @author Jonas Jacobi + */ +QString accessSpecifierToString(CodeModelItem::Access access); + + +class CodeModelHelper +{ +private: + CodeModel* m_model; + FileList m_files; + QString m_fileName; + + FunctionDefinitionDom functionDefinitionAt(NamespaceDom ns, int line, int column); + + FunctionDefinitionDom functionDefinitionAt(ClassDom klass, int line, int column); + + FunctionDefinitionDom functionDefinitionAt(FunctionDefinitionDom fun, int line, int); + + FunctionDom functionDeclarationAt(NamespaceDom ns, int line, int column); + + FunctionDom functionDeclarationAt(ClassDom klass, int line, int column); + + FunctionDom functionDeclarationAt(FunctionDom fun, int line, int column); + + + ClassDom classAt(NamespaceDom ns, int line, int column); + + ClassDom classAt(ClassDom klass, int line, int column); + +public: + CodeModelHelper(CodeModel* model, FileDom file); + + enum FunctionTypes { + Declaration = 1, + Definition = 2 + }; + + FunctionDom functionAt(int line, int column, FunctionTypes types = (FunctionTypes)3); + ClassDom classAt(int line, int column); +}; + +} + +#endif diff -Nru umbrello-4.12.3/lib/interfaces/hashedstring.cpp umbrello-4.12.90/lib/interfaces/hashedstring.cpp --- umbrello-4.12.3/lib/interfaces/hashedstring.cpp 1970-01-01 00:00:00.000000000 +0000 +++ umbrello-4.12.90/lib/interfaces/hashedstring.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -0,0 +1,391 @@ +/*************************************************************************** + copyright : (C) 2006 by David Nolden + email : david.nolden.kdevelop@art-master.de +***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "hashedstring.h" +#include +#include +#include +#include +#include +#include +#include + +//It needs to be measured whether this flag should be turned on or off. It seems just to move the complexity from one position to the other, without any variant being really better. +#define USE_HASHMAP + +size_t fastHashString(const QString& str); + +size_t hashStringSafe(const QString& str) +{ + size_t hash = 0; + int len = str.length(); + for (int a = 0; a < len; a++) { + hash = str[a].unicode() + (hash * 17); + } + return hash; +} + +size_t HashedString::hashString(const QString& str) +{ + return fastHashString(str); +} + +size_t fastHashString(const QString& str) +{ + size_t hash = 0; + if (!str.isEmpty()) { + const QChar* curr = str.unicode(); + const QChar* end = curr + str.length(); + QChar c; + for (; curr < end ;) { + c = *curr; + hash = c.unicode() + (hash * 17); + ++curr; + } + } + return hash; +} + +void HashedString::initHash() +{ + m_hash = hashString(m_str); +} + + +class HashedStringSetData : public KShared +{ +public: +#ifdef USE_HASHMAP + typedef __gnu_cxx::hash_set StringSet; +#else + typedef std::set StringSet; //must be a set, so the set-algorithms work +#endif + StringSet m_files; + mutable bool m_hashValid; + mutable size_t m_hash; + HashedStringSetData() : m_hashValid(false) + { + } + inline void invalidateHash() + { + m_hashValid = false; + } + + void computeHash() const; +}; + +void HashedStringSetData::computeHash() const +{ + int num = 1; + m_hash = 0; + for (StringSet::const_iterator it = m_files.begin(); it != m_files.end(); ++it) { + num *= 7; + m_hash += num * (*it).hash(); + } + m_hashValid = true; +} + +HashedStringSet::HashedStringSet() {} + +HashedStringSet::~HashedStringSet() {} + +HashedStringSet::HashedStringSet(const HashedString& file) +{ + insert(file); +} + +HashedStringSet::HashedStringSet(const HashedStringSet& rhs) : m_data(rhs.m_data) {} + +HashedStringSet operator + (const HashedStringSet& lhs, const HashedStringSet& rhs) +{ + HashedStringSet ret = lhs; + ret += rhs; + + return ret; +} + +int HashedStringSet::size() const +{ + if (!m_data) return 0; + return m_data->m_files.size(); +} + +HashedStringSet& HashedStringSet::operator = (const HashedStringSet& rhs) +{ + m_data = rhs.m_data; + return *this; +} + +HashedStringSet& HashedStringSet::operator +=(const HashedStringSet& rhs) +{ + if (!rhs.m_data) + return * this; + +#ifndef USE_HASHMAP + KSharedPtr oldData = m_data; + if (!oldData) oldData = new HashedStringSetData(); + m_data = new HashedStringSetData(); + std::set_union(oldData->m_files.begin(), oldData->m_files.end(), rhs.m_data->m_files.begin(), rhs.m_data->m_files.end(), std::insert_iterator(m_data->m_files, m_data->m_files.end())); +#else + makeDataPrivate(); + m_data->m_files.insert(rhs.m_data->m_files.begin(), rhs.m_data->m_files.end()); + /*HashedStringSetData::StringSet::const_iterator end = rhs.m_data->m_files.end(); + HashedStringSetData::StringSet& mySet(m_data->m_files); + for(HashedStringSetData::StringSet::const_iterator it = rhs.m_data->m_files.begin(); it != end; ++it) { + mySet.insert(*it); + }*/ + +#endif + return *this; +} + +HashedStringSet& HashedStringSet::operator -=(const HashedStringSet& rhs) +{ + if (!m_data) return *this; + if (!rhs.m_data) return *this; +#ifndef USE_HASHMAP + KSharedPtr oldData = m_data; + m_data = new HashedStringSetData(); + std::set_difference(oldData->m_files.begin(), oldData->m_files.end(), rhs.m_data->m_files.begin(), rhs.m_data->m_files.end(), std::insert_iterator(m_data->m_files, m_data->m_files.end())); +#else + makeDataPrivate(); + HashedStringSetData::StringSet::const_iterator end = rhs.m_data->m_files.end(); + HashedStringSetData::StringSet& mySet(m_data->m_files); + for (HashedStringSetData::StringSet::const_iterator it = rhs.m_data->m_files.begin(); it != end; ++it) { + mySet.erase(*it); + } + +#endif + return *this; +} + + +void HashedStringSet::makeDataPrivate() +{ + if (!m_data) { + m_data = new HashedStringSetData(); + return ; + } + if (m_data.count() != 1) + m_data = new HashedStringSetData(*m_data); +} + +bool HashedStringSet::operator[] (const HashedString& rhs) const +{ + //if (rhs.str() == "*") + //return true; /// * stands for "any file" + if (!m_data) + return false; + return m_data->m_files.find(rhs) != m_data->m_files.end(); +} + +void HashedStringSet::insert(const HashedString& str) +{ + if (str.str().isEmpty()) return; + makeDataPrivate(); + m_data->m_files.insert(str); + m_data->invalidateHash(); +} + +bool HashedStringSet::operator <= (const HashedStringSet& rhs) const +{ + if (!m_data) + return true; + if (m_data->m_files.empty()) + return true; + if (!rhs.m_data) + return false; +#ifndef USE_HASHMAP + return std::includes(rhs.m_data->m_files.begin(), rhs.m_data->m_files.end(), m_data->m_files.begin(), m_data->m_files.end()); +#else + const HashedStringSetData::StringSet& otherSet(rhs.m_data->m_files); + HashedStringSetData::StringSet::const_iterator end = rhs.m_data->m_files.end(); + HashedStringSetData::StringSet::const_iterator myEnd = m_data->m_files.end(); + + for (HashedStringSetData::StringSet::const_iterator it = m_data->m_files.begin(); it != myEnd; ++it) { + HashedStringSetData::StringSet::const_iterator i = otherSet.find(*it); + if (i == end) return false; + } + return true; +#endif +} + +bool HashedStringSet::operator == (const HashedStringSet& rhs) const +{ + if (hash() != rhs.hash()) return false; + + bool empty1 = false; + if (!m_data) + empty1 = true; + else if (m_data->m_files.empty()) + empty1 = true; + bool empty2 = false; + if (!rhs.m_data) + empty2 = true; + else if (rhs.m_data->m_files.empty()) + empty2 = true; + + if (empty1 && empty2) + return true; + if (empty1 || empty2) + return false; + + return m_data->m_files == rhs.m_data->m_files; +} + +size_t HashedStringSet::hash() const +{ + if (!m_data) return 0; + if (!m_data->m_hashValid) m_data->computeHash(); + return m_data->m_hash; +} + +void HashedStringSet::read(QDataStream& stream) +{ + bool b; + stream >> b; + if (b) { + m_data = new HashedStringSetData(); + int cnt; + stream >> cnt; + HashedString s; + for (int a = 0; a < cnt; a++) { + stream >> s; + m_data->m_files.insert(s); + } + } else { + m_data = 0; + } +} + +void HashedStringSet::write(QDataStream& stream) const +{ + bool b = m_data; + stream << b; + if (b) { + int cnt = m_data->m_files.size(); + stream << cnt; + for (HashedStringSetData::StringSet::const_iterator it = m_data->m_files.begin(); it != m_data->m_files.end(); ++it) { + stream << *it; + } + } +} + +std::string HashedStringSet::print() const +{ + std::ostringstream s; + if (m_data) { + for (HashedStringSetData::StringSet::const_iterator it = m_data->m_files.begin(); it != m_data->m_files.end(); ++it) { + s << (*it).str().toLatin1().data() << "\n"; + } + } + return s.str(); +} + +QDataStream& operator << (QDataStream& stream, const HashedString& str) +{ + stream << str.m_str; + stream << str.m_hash; + return stream; +} + +QDataStream& operator >> (QDataStream& stream, HashedString& str) +{ + stream >> str.m_str; + stream >> str.m_hash; + return stream; +} + +void HashedStringSetGroup::addSet(size_t id, const HashedStringSet& set) +{ + if (set.m_data && !set.m_data->m_files.empty()) { + m_sizeMap[ id ] = set.size(); + for (HashedStringSetData::StringSet::const_iterator it = set.m_data->m_files.begin(); it != set.m_data->m_files.end(); ++it) { + GroupMap::iterator itr = m_map.find(*it); + if (itr == m_map.end()) { + itr = m_map.insert(std::make_pair(*it, ItemSet())).first; + } + itr->second.insert(id); + } + } else { + m_global.insert(id); + } +} + +void HashedStringSetGroup::disableSet(size_t id) +{ + m_disabled.insert(id); +} + +void HashedStringSetGroup::enableSet(size_t id) +{ + m_disabled.erase(id); +} + +bool HashedStringSetGroup::isDisabled(size_t id) const +{ + return m_disabled.find(id) != m_disabled.end(); +} + +void HashedStringSetGroup::removeSet(size_t id) +{ + m_disabled.erase(id); + m_global.erase(id); + m_sizeMap.erase(id); + for (GroupMap::iterator it = m_map.begin(); it != m_map.end(); ++it) { + it->second.erase(id); + } +} + +void HashedStringSetGroup::findGroups(HashedStringSet strings, ItemSet& target) const +{ + target.clear(); + if (!strings.m_data) { + std::set_difference(m_global.begin(), m_global.end(), m_disabled.begin(), m_disabled.end(), std::insert_iterator(target, target.end())); + return; + } + //This might yet be optimized by sorting the sets according to their size, and starting the intersectioning with the smallest ones. + __gnu_cxx::hash_map hitCounts; + + for (HashedStringSetData::StringSet::const_iterator it = strings.m_data->m_files.begin(); it != strings.m_data->m_files.end(); ++it) { + GroupMap::const_iterator itr = m_map.find(*it); + if (itr == m_map.end()) { + //There are no string-sets that include the currently searched for string + continue; + } + + for (ItemSet::const_iterator it2 = itr->second.begin(); it2 != itr->second.end(); ++it2) { + __gnu_cxx::hash_map::iterator v = hitCounts.find(*it2); + if (v != hitCounts.end()) { + ++(*v).second; + } else { + hitCounts[*it2] = 1; + } + } + } + + //Now count together all groups that are completely within the given string-set(their hitCount equals their size) + ItemSet found; + for (__gnu_cxx::hash_map::const_iterator it = hitCounts.begin(); it != hitCounts.end(); ++it) { + if ((*it).second == (*m_sizeMap.find((*it).first)).second) + found.insert((*it).first); + } + + + std::set_union(found.begin(), found.end(), m_global.begin(), m_global.end(), std::insert_iterator(target, target.end())); + + target.swap(found); + target.clear(); + std::set_difference(found.begin(), found.end(), m_disabled.begin(), m_disabled.end(), std::insert_iterator(target, target.end())); +} diff -Nru umbrello-4.12.3/lib/interfaces/hashedstring.h umbrello-4.12.90/lib/interfaces/hashedstring.h --- umbrello-4.12.3/lib/interfaces/hashedstring.h 1970-01-01 00:00:00.000000000 +0000 +++ umbrello-4.12.90/lib/interfaces/hashedstring.h 2014-03-05 15:04:09.000000000 +0000 @@ -0,0 +1,167 @@ +/*************************************************************************** + copyright : (C) 2006 by David Nolden + email : david.nolden.kdevelop@art-master.de +***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef HASHED_STRING_H +#define HASHED_STRING_H + +#include "ast.h" + +#include +#include +#include +#include +#include + +///A simple class that stores a string together with it's appropriate hash-key +class HashedString +{ +public: + HashedString() : m_hash(0) {} + + HashedString(const QString& str) : m_str(str) + { + initHash(); + } + + HashedString(const char* str) : m_str(str) + { + initHash(); + } + + inline size_t hash() const + { + return m_hash; + } + + QString str() const + { + return m_str; + } + + bool operator == (const HashedString& rhs) const + { + if (m_hash != rhs.m_hash) + return false; + return m_str == rhs.m_str; + } + + ///Does not compare alphabetically, uses the hash-key for ordering. + bool operator < (const HashedString& rhs) const + { + if (m_hash < rhs.m_hash) + return true; + if (m_hash == rhs.m_hash) + return m_str < rhs.m_str; + return false; + } + + static size_t hashString(const QString& str); + +private: + void initHash(); + + QString m_str; + size_t m_hash; + + friend QDataStream& operator << (QDataStream& stream, const HashedString& str); + friend QDataStream& operator >> (QDataStream& stream, HashedString& str); +}; + +QDataStream& operator << (QDataStream& stream, const HashedString& str); + +QDataStream& operator >> (QDataStream& stream, HashedString& str); + +class HashedStringSetData; +class HashedStringSetGroup; + +///This is a reference-counting string-set optimized for fast lookup of hashed strings +class HashedStringSet +{ +public: + HashedStringSet(); + + ~HashedStringSet(); + + ///Constructs a string-set from one single file + HashedStringSet(const HashedString& file); + + HashedStringSet(const HashedStringSet& rhs); + + int size() const; + + HashedStringSet& operator = (const HashedStringSet& rhs); + ///@return whether the given file-name was included + bool operator[] (const HashedString& rhs) const; + + void insert(const HashedString& str); + + HashedStringSet& operator +=(const HashedStringSet&); + + HashedStringSet& operator -=(const HashedStringSet&); + + ///intersection-test + ///Returns true if all files that are part of this set are also part of the given set + bool operator <= (const HashedStringSet& rhs) const; + + bool operator == (const HashedStringSet& rhs) const; + + void read(QDataStream& stream); + void write(QDataStream& stream) const; + + std::string print() const; + + size_t hash() const; +private: + friend class HashedStringSetGroup; + void makeDataPrivate(); + KSharedPtr m_data; //this implies some additional cost because KShared's destructor is virtual. Maybe change that by copying KShared without the virtual destructor. + friend HashedStringSet operator + (const HashedStringSet& lhs, const HashedStringSet& rhs); +}; + +HashedStringSet operator + (const HashedStringSet& lhs, const HashedStringSet& rhs); + +namespace __gnu_cxx +{ +template<> +struct hash { + size_t operator () (const HashedString& str) const + { + return str.hash(); + } +}; +} + +///Used to find all registered HashedStringSet's that contain all strings given to findGroups(..) +class HashedStringSetGroup +{ +public: + typedef std::set ItemSet; + void addSet(size_t id, const HashedStringSet& set); + void enableSet(size_t id); + bool isDisabled(size_t id) const; + void disableSet(size_t id); + void removeSet(size_t id); + + //Writes the ids of all registered and not disabled HashedStringSet's that are completely included in the given HashedStringSet efficiently) + void findGroups(HashedStringSet strings, ItemSet& target) const; + +private: + typedef __gnu_cxx::hash_map GroupMap; + typedef __gnu_cxx::hash_map SizeMap; + GroupMap m_map; + SizeMap m_sizeMap; + ItemSet m_disabled; + ItemSet m_global; +}; +#endif diff -Nru umbrello-4.12.3/lib/interfaces/kdatastream.h umbrello-4.12.90/lib/interfaces/kdatastream.h --- umbrello-4.12.3/lib/interfaces/kdatastream.h 1970-01-01 00:00:00.000000000 +0000 +++ umbrello-4.12.90/lib/interfaces/kdatastream.h 2014-03-05 15:04:09.000000000 +0000 @@ -0,0 +1,73 @@ +#ifndef __kdatastream__h +#define __kdatastream__h + +#include + +#ifdef USE_QT3 +inline QDataStream & operator << (QDataStream & str, bool b) +{ + str << Q_INT8(b); + return str; +} + +inline QDataStream & operator >> (QDataStream & str, bool & b) +{ + Q_INT8 l; + str >> l; + b = bool(l); + return str; +} +#endif // USE_QT3 + +#if QT_VERSION < 0x030200 && !defined(Q_WS_WIN) && !defined(Q_WS_MAC) +inline QDataStream & operator << (QDataStream & str, long long int ll) +{ + Q_UINT32 l1,l2; + l1 = ll & 0xffffffffLL; + l2 = ll >> 32; + str << l1 << l2; + return str; +} + +inline QDataStream & operator >> (QDataStream & str, long long int&ll) +{ + Q_UINT32 l1,l2; + str >> l1 >> l2; + ll = ((unsigned long long int)(l2) << 32) + (long long int) l1; + return str; +} + +inline QDataStream & operator << (QDataStream & str, unsigned long long int ll) +{ + Q_UINT32 l1,l2; + l1 = ll & 0xffffffffLL; + l2 = ll >> 32; + str << l1 << l2; + return str; +} + +inline QDataStream & operator >> (QDataStream & str, unsigned long long int &ll) +{ + Q_UINT32 l1,l2; + str >> l1 >> l2; + ll = ((unsigned long long int)(l2) << 32) + (unsigned long long int) l1; + return str; +} +#endif + +inline QDataStream & operator >> (QDataStream & str, long unsigned int &ll) +{ + return str >> ((unsigned int &)ll); +} + +inline QDataStream &operator << (QDataStream &str, long unsigned int &ll) +{ + return str << ((unsigned int &)ll); +} + +inline QDataStream &operator << (QDataStream &str, const long unsigned int &ll) +{ + return str << ((unsigned int &)ll); +} + +#endif diff -Nru umbrello-4.12.3/maintainer/git-tags umbrello-4.12.90/maintainer/git-tags --- umbrello-4.12.3/maintainer/git-tags 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/maintainer/git-tags 2014-03-05 15:04:09.000000000 +0000 @@ -2,4 +2,4 @@ # # list tags and related dates # -git for-each-ref --format '%(refname) %(taggerdate)' refs/tags +git for-each-ref --format '%(refname) %(taggerdate) %(objectname)' refs/tags | sort -t. -k 1.12,1 -k 2n,2 diff -Nru umbrello-4.12.3/THANKS umbrello-4.12.90/THANKS --- umbrello-4.12.3/THANKS 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/THANKS 2014-03-05 15:04:09.000000000 +0000 @@ -38,7 +38,7 @@ Andi Fischer Pascal Fleury JP Fournier -Aurélien Gâteau +Aurelien Gateau Gregorio Guidi Jose Gutierrez Ralf Habacker @@ -50,7 +50,7 @@ Michel Hermier Harald Herres David Hugh-Jones -Pekka Jääskeläinen +Pekka Jaaskeläinen Klas Kalass Oliver Kellogg Kleag (kleag @free.fr) @@ -84,13 +84,14 @@ Matt Rogers Peeter Russak Paulo Roberto Rodriguez Sehn -Daniel Calviño Sánchez +Daniel Calvino Sanchez Leo Savernik Carlo Segato Frederik Schwarzer Peter Soetens Achim Spangler Sebastian Stein +Joris Steyn Andrew Sutton Tanuj Brian Thomas diff -Nru umbrello-4.12.3/umbrello/association.cpp umbrello-4.12.90/umbrello/association.cpp --- umbrello-4.12.3/umbrello/association.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/association.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -637,8 +637,9 @@ */ void UMLAssociation::setMultiplicity(const QString &multi, Uml::RoleType::Enum role) { - UMLApp::app()->executeCommand(new CmdChangeMultiplicity(m_pRole[role], multi)); - //m_pRole[role]->setMultiplicity(multi); + if (m_pRole[role]->multiplicity() != multi) { + UMLApp::app()->executeCommand(new CmdChangeMultiplicity(m_pRole[role], multi)); + } } /** diff -Nru umbrello-4.12.3/umbrello/basictypes.cpp umbrello-4.12.90/umbrello/basictypes.cpp --- umbrello-4.12.3/umbrello/basictypes.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/basictypes.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -818,7 +818,7 @@ case JavaScript: return QString("JavaScript"); case MySQL: - return QString("MySQL"); + return QString("MySQL"); case Pascal: return QString("Pascal"); case Perl: @@ -905,6 +905,78 @@ return Enum(item); } +/** + * Return extensions associated with the requested language. + * @param item programming language index + * @return extensions list + */ +QStringList toExtensions(Enum item) +{ + QStringList result; + switch (item) { //:TODO: More languages? + case Uml::ProgrammingLanguage::Ada: + result << "*.ads" << "*.adb" << "*.ada"; + break; + case Uml::ProgrammingLanguage::Cpp: + result << "*.h" << "*.hpp" << "*.hh" << "*.hxx" << "*.H"; + break; + case Uml::ProgrammingLanguage::IDL: + result << "*.idl"; + break; + case Uml::ProgrammingLanguage::Java: + result << "*.java"; + break; + case Uml::ProgrammingLanguage::Pascal: + result << "*.pas"; + break; + case Uml::ProgrammingLanguage::Python: + result << "*.py" << "*.pyw"; + break; + case Uml::ProgrammingLanguage::CSharp: + result << "*.cs"; + break; + default: + break; + } + return result; +} + +/** + * Return clear text file extension description for the requested language. + * @param item programming language index + * @return extension + */ +QString toExtensionsDescription(Enum item) +{ + QString result = "Files"; + switch (item) { //:TODO: More languages? + case Uml::ProgrammingLanguage::Ada: + result = "Source files"; + break; + case Uml::ProgrammingLanguage::Cpp: + result = "Header files"; + break; + case Uml::ProgrammingLanguage::IDL: + result = "Source files"; + break; + case Uml::ProgrammingLanguage::Java: + result = "Source files"; + break; + case Uml::ProgrammingLanguage::Pascal: + result = "Source files"; + break; + case Uml::ProgrammingLanguage::Python: + result = "Source files"; + break; + case Uml::ProgrammingLanguage::CSharp: + result = "Source files"; + break; + default: + break; + } + return toString(item) + QLatin1String(" ") + result; +} + } // end namespace ProgrammingLanguage //----------------------------------------------------------------------------- diff -Nru umbrello-4.12.3/umbrello/basictypes.h umbrello-4.12.90/umbrello/basictypes.h --- umbrello-4.12.3/umbrello/basictypes.h 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/basictypes.h 2014-03-05 15:04:09.000000000 +0000 @@ -264,6 +264,8 @@ QString toString(Enum item); Enum fromString(const QString& item); Enum fromInt(int item); + QStringList toExtensions(Enum item); + QString toExtensionsDescription(Enum item); } /** diff -Nru umbrello-4.12.3/umbrello/classifiercodedocument.cpp umbrello-4.12.90/umbrello/classifiercodedocument.cpp --- umbrello-4.12.3/umbrello/classifiercodedocument.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/classifiercodedocument.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -695,7 +695,7 @@ m_classFieldMap.insert(cf->getParentObject(), cf); } else - uError()<<" LoadFromXMI: can not load classfield parent_id:"<addParm(par); } } - if (nameNotSet || params == NULL) { - if (nameNotSet) - op->setName(uniqChildName(UMLObject::ot_Operation)); + + // Only show the operation dialog if no name was provided (allows quick-create + // from listview) + if (nameNotSet) { + op->setName(uniqChildName(UMLObject::ot_Operation)); + while (true) { QPointer operationDialog = new UMLOperationDialog(0, op); if(operationDialog->exec() != KDialog::Accepted) { @@ -274,7 +277,7 @@ return NULL; } else if (checkOperationSignature(op->name(), op->getParmList())) { KMessageBox::information(0, - i18n("An operation with the same name and signature already exists. You can not add it again.")); + i18n("An operation with the same name and signature already exists. You cannot add it again.")); } else { break; } @@ -1521,6 +1524,7 @@ continue; element = node.toElement(); QString tag = element.tagName(); + QString stereotype = element.attribute("stereotype"); if (UMLDoc::tagEq(tag, "ModelElement.templateParameter") || UMLDoc::tagEq(tag, "Classifier.feature") || UMLDoc::tagEq(tag, "Namespace.ownedElement") || @@ -1554,7 +1558,7 @@ totalSuccess = false; } } else if (!Model_Utils::isCommonXMIAttribute(tag)) { - UMLObject *pObject = Object_Factory::makeObjectFromXMI(tag); + UMLObject *pObject = Object_Factory::makeObjectFromXMI(tag, stereotype); if (pObject == NULL) { // Not setting totalSuccess to false // because we want a best effort. diff -Nru umbrello-4.12.3/umbrello/clipboard/umlclipboard.cpp umbrello-4.12.90/umbrello/clipboard/umlclipboard.cpp --- umbrello-4.12.3/umbrello/clipboard/umlclipboard.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/clipboard/umlclipboard.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -65,9 +65,8 @@ */ QMimeData* UMLClipboard::copy(bool fromView/*=false*/) { - //Clear previous copied data + // Clear previous copied data m_AssociationList.clear(); - m_ItemList.clear(); m_ObjectList.clear(); m_ViewList.clear(); @@ -92,60 +91,58 @@ // is no longer there when pasting this mime data. This happens for // example when using cut-paste or pasting to another Umbrello // instance. - foreach (WidgetBase* widget, m_WidgetList) { - if (widget->umlObject() != 0) { - m_ObjectList.append(widget->umlObject()); - } - } + fillObjectListForWidgets(m_WidgetList); foreach (WidgetBase* widget, m_AssociationList) { if (widget->umlObject() != 0) { m_ObjectList.append(widget->umlObject()); } } - } else { //if the copy action is being performed from the ListView + } else { + // The copy action is being performed from the ListView UMLListViewItemList itemsSelected = listView->selectedItems(); if (itemsSelected.count() <= 0) { return 0; } - //Set What type of copy operation are we performing and - //also fill m_ViewList with all the selected Diagrams + + // Set What type of copy operation are we performing and + // also fill m_ViewList with all the selected Diagrams setCopyType(itemsSelected); - //if we are copying a diagram or part of a diagram, select the items - //on the ListView that correspond to a UseCase, Actor or Concept - //in the Diagram + // If we are copying a diagram or part of a diagram, select the items + // on the ListView that correspond to a UseCase, Actor or Concept + // in the Diagram if (m_type == clip2) { - //Fill the member lists with all the object and stuff to be copied - //to the clipboard - itemsSelected.clear(); - //For each selected view select all the Actors, USe Cases and Concepts - //widgets in the ListView foreach (UMLView* view, m_ViewList) { - UMLObjectList objects = view->umlScene()->umlObjects(); - foreach (UMLObject* o, objects) { - UMLListViewItem *item = listView->findUMLObject(o); - if (item) { - listView->setCurrentItem(item); + fillObjectListForWidgets(view->umlScene()->widgetList()); + + AssociationWidgetList associations = view->umlScene()->associationList(); + foreach (AssociationWidget* association, associations) { + if (association->umlObject() != 0) { + m_ObjectList.append(association->umlObject()); } } } - itemsSelected = listView->selectedItems(); + } else { + // Clip1, 4 and 5: fill the clip with only the specific objects + // selected in the list view + if (!fillSelectionLists(itemsSelected)) { + return 0; + } + if (itemsSelected.count() <= 0) { return 0; } } - if (!fillSelectionLists(itemsSelected)) { - return 0; - } } + int i = 0; switch(m_type) { case clip1: data = new UMLDragData(m_ObjectList); break; case clip2: - data = new UMLDragData(m_ObjectList, m_ItemList, m_ViewList); + data = new UMLDragData(m_ObjectList, m_ViewList); break; case clip3: data = new UMLDragData(m_ItemList); @@ -178,9 +175,16 @@ bool UMLClipboard::paste(const QMimeData* data) { UMLDoc *doc = UMLApp::app()->document(); + + int codingType = UMLDragData::getCodingType(data); + + QString mimeType = "application/x-uml-clip" + QString::number(codingType); + uDebug() << "Pasting mimeType=" << mimeType << "data=" << data->data(mimeType); + bool result = false; doc->beginPaste(); - switch(UMLDragData::getCodingType(data)) { + + switch (codingType) { case 1: result = pasteClip1(data); break; @@ -204,6 +208,41 @@ } /** + * Fills object list based on a selection of widgets + * + * @param UMLWidgetList& widgets + */ +void UMLClipboard::fillObjectListForWidgets(UMLWidgetList& widgets) +{ + // The order of the packages in the clip matters. So we collect + // the packages and add them from the root package to the deeper levels + UMLObjectList packages; + + foreach (UMLWidget* widget, widgets) { + UMLObject* widgetObject = widget->umlObject(); + if (widgetObject != 0) { + packages.clear(); + + UMLPackage* package = widgetObject->umlPackage(); + while (package != 0) { + packages.prepend(package); + package = package->umlPackage(); + } + + foreach (UMLObject* package, packages) { + if (!m_ObjectList.contains(package)) { + m_ObjectList.append(package); + } + } + + if (!m_ObjectList.contains(widgetObject)) { + m_ObjectList.append(widgetObject); + } + } + } +} + +/** * Fills the member lists with all the objects and other * stuff to be copied to the clipboard. * @param selectedItems list of selected items @@ -220,12 +259,6 @@ if (!Model_Utils::typeIsClassifierList(type)) { m_ItemList.append(item); insertItemChildren(item, selectedItems); - //Because it is being called when m_type is 3 - //it will insert only child empty folders of other folders. - //If a child folder - //is not empty that means m_type wouldn't be 3 because if a folder is - //selected then its complete contents are treated as if - //they were selected } } break; @@ -234,9 +267,6 @@ foreach (UMLListViewItem* item, selectedItems) { type = item->type(); if (!Model_Utils::typeIsClassifierList(type)) { - - m_ItemList.append(item); - if (Model_Utils::typeIsCanvasWidget(type)) { m_ObjectList.append(item->umlObject()); } @@ -248,9 +278,7 @@ foreach (UMLListViewItem* item, selectedItems) { type = item->type(); if(Model_Utils::typeIsClassifierList(type)) { - m_ItemList.append(item); m_ObjectList.append(item->umlObject()); - } else { return false; } @@ -324,7 +352,8 @@ } /** - * Adds the children of a UMLListViewItem to m_ItemList. + * Traverse children of a UMLListViewItem and add its UMLObjects to the list + * * @param item parent of the children to insert * @param selectedItems list of selected items * @return success flag @@ -335,10 +364,9 @@ for(int i = 0; i < item->childCount(); i++) { UMLListViewItem * child = (UMLListViewItem*)item->child(i); m_ItemList.append(child); - int type = child->type(); - if (type == UMLListViewItem::lvt_Actor || - type == UMLListViewItem::lvt_UseCase || - type == UMLListViewItem::lvt_Class) { + UMLListViewItem::ListViewType type = child->type(); + if (!Model_Utils::typeIsClassifierList(type) && + !Model_Utils::typeIsDiagram(type)) { m_ObjectList.append(child->umlObject()); } // If the child is selected, remove it from the list of selected items @@ -353,58 +381,6 @@ } /** - * Pastes the children of a UMLListViewItem (The Parent) - * @param parent parent of the children - * @param chgLog ID change log - * @return success flag - */ -bool UMLClipboard::pasteChildren(UMLListViewItem *parent, IDChangeLog *chgLog) -{ - if (!parent) { - uWarning() << "Paste Children Error, parent missing"; - return false; - } - UMLDoc *doc = UMLApp::app()->document(); - UMLListView *listView = UMLApp::app()->listView(); - for (int i = 0; i < parent->childCount(); i++) { - UMLListViewItem *childItem = static_cast(parent->child(i)); - Uml::ID::Type oldID = childItem->ID(); - Uml::ID::Type newID = chgLog->findNewID(oldID); - UMLListViewItem *shouldNotExist = listView->findItem(newID); - if (shouldNotExist) { - uError() << "new list view item " << Uml::ID::toString(newID) - << " already exists (internal error)"; - continue; - } - UMLObject *newObj = doc->findObjectById(newID); - if (newObj) { - uDebug() << "adjusting lvitem(" << Uml::ID::toString(oldID) - << ") to new UMLObject(" << Uml::ID::toString(newID) << ")"; - childItem->setUMLObject(newObj); - childItem->setText(newObj->name()); - } else { - uDebug() << "no UMLObject found for lvitem " << Uml::ID::toString(newID); - } - } - return true; -} - -/** - * Cleans the list of associations taking out the ones that point to an object - * not in m_ObjectList. - * @param associations list of associations - */ -void UMLClipboard::CleanAssociations(AssociationWidgetList& associations) -{ - AssociationWidgetListIt it(associations); - - while (it.hasNext()) { - AssociationWidget* assoc = it.next(); - Q_UNUSED(assoc); - } -} - -/** * If clipboard has mime type application/x-uml-clip1, * Pastes the data from the clipboard into the current Doc. * @param data mime type @@ -412,27 +388,7 @@ bool UMLClipboard::pasteClip1(const QMimeData* data) { UMLObjectList objects; - if (! UMLDragData::decodeClip1(data, objects)) { - return false; - } - UMLListView *lv = UMLApp::app()->listView(); - if (!lv->startedCopy()) - return true; - lv->setStartedCopy(false); - /* If we get here we are pasting after a Copy and need to - // paste possible children. - UMLListViewItem* itemdata = 0; - UMLListViewItemListIt it(itemdatalist); - while ((itemdata=it.current()) != 0) { - if(itemdata->childCount()) { - if(!pasteChildren(itemdata, idchanges)) { - return false; - } - } - ++it; - } - */ - return true; + return UMLDragData::decodeClip1(data, objects); } /** @@ -444,39 +400,33 @@ bool UMLClipboard::pasteClip2(const QMimeData* data) { UMLDoc* doc = UMLApp::app()->document(); - UMLListViewItemList itemdatalist; UMLObjectList objects; UMLViewList views; - IDChangeLog* idchanges = 0; - bool result = UMLDragData::decodeClip2(data, objects, itemdatalist, views); - if(!result) { + if (!UMLDragData::decodeClip2(data, objects, views)) { return false; } - idchanges = doc->changeLog(); - if(!idchanges) { - return false; - } - foreach (UMLObject* obj, objects) { - if(!doc->assignNewIDs(obj)) { - uDebug() << "UMLClipboard: error adding umlobject"; - return false; - } - } - foreach (UMLView* pView, views) { if(!doc->addUMLView(pView)) { return false; } } - return result; + return true; } /** * If clipboard has mime type application/x-uml-clip3, * Pastes the data from the clipboard into the current Doc. + * + * Note: clip3 is only used to determine if the selected items can be dragged + * onto the view. Pasting only listview items makes no sense. Clip3 is implemented + * as a fallback-clip when clip 1, 2, 4 or 5 are not applicable. But that should + * never happen. + * + * Todo: remove clip3 alltogether. + * * @param data mime type * @return success flag */ @@ -491,12 +441,7 @@ } UMLListView *listView = UMLApp::app()->listView(); - bool result = UMLDragData::decodeClip3(data, itemdatalist, listView); - if(!result) { - return false; - } - - return result; + return UMLDragData::decodeClip3(data, itemdatalist, listView); } /** @@ -564,10 +509,6 @@ currentScene->type() == Uml::DiagramType::State) { widget->setID(doc->assignNewID(widget->id())); } - if (! currentScene->addWidget(widget, true)) { - currentScene->endPartialWidgetPaste(); - return false; - } } } @@ -740,24 +681,6 @@ } /** - * Inserts the data of the children of the given item - * into the item data list. Used for clip type 4. Used - * to make * sure classes have all the attributes and - * operations saved. - * @param item parent item, its children are inserted - * @return success flag - */ -bool UMLClipboard::insertItemChildren(UMLListViewItem * item) -{ - for (int i = 0; i < item->childCount(); i++) { - UMLListViewItem * child =dynamic_cast(item->child(i)); - m_ItemList.append(child); - insertItemChildren(child); - } - return true; -} - -/** * When pasting widgets see if they can be pasted on * different diagram types. Will return true if all the * widgets to be pasted can be. At the moment this only diff -Nru umbrello-4.12.3/umbrello/clipboard/umlclipboard.h umbrello-4.12.90/umbrello/clipboard/umlclipboard.h --- umbrello-4.12.3/umbrello/clipboard/umlclipboard.h 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/clipboard/umlclipboard.h 2014-03-05 15:04:09.000000000 +0000 @@ -55,8 +55,6 @@ private: - void CleanAssociations(AssociationWidgetList& associations); - bool pasteClip1(const QMimeData* data); bool pasteClip2(const QMimeData* data); bool pasteClip3(const QMimeData* data); @@ -74,6 +72,8 @@ private: + void fillObjectListForWidgets(UMLWidgetList& widgets); + bool fillSelectionLists(UMLListViewItemList& selectedItems); void setCopyType(UMLListViewItemList& selectedItems); @@ -86,10 +86,6 @@ bool insertItemChildren(UMLListViewItem* item, UMLListViewItemList& selectedItems); - bool insertItemChildren(UMLListViewItem* item); - - bool pasteChildren(UMLListViewItem* parent, IDChangeLog *chgLog); - void pasteItemAlreadyExists(); }; diff -Nru umbrello-4.12.3/umbrello/clipboard/umldragdata.cpp umbrello-4.12.90/umbrello/clipboard/umldragdata.cpp --- umbrello-4.12.3/umbrello/clipboard/umldragdata.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/clipboard/umldragdata.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -12,21 +12,26 @@ #include "umldragdata.h" // local includes +#include "associationwidget.h" +#include "classifier.h" +#include "cmds.h" #include "debug_utils.h" +#include "folder.h" #include "idchangelog.h" +#include "model_utils.h" +#include "object_factory.h" +#include "objectwidget.h" +#include "preconditionwidget.h" +#include "messagewidget.h" +#include "uniqueid.h" #include "uml.h" #include "umldoc.h" +#include "umllistview.h" +#include "umllistviewitem.h" +#include "umlobject.h" #include "umlscene.h" #include "umlview.h" -#include "umlobject.h" -#include "folder.h" -#include "classifier.h" #include "umlwidget.h" -#include "umllistview.h" -#include "umllistviewitem.h" -#include "associationwidget.h" -#include "object_factory.h" -#include "model_utils.h" // qt includes #include @@ -47,11 +52,10 @@ * from the ListView to be copied, Mime type = * "application/x-uml-clip2 */ -UMLDragData::UMLDragData(UMLObjectList& objects, UMLListViewItemList& umlListViewItems, - UMLViewList& diagrams, QWidget* dragSource /* = 0 */) +UMLDragData::UMLDragData(UMLObjectList& objects, UMLViewList& diagrams, QWidget* dragSource /* = 0 */) { Q_UNUSED(dragSource); - setUMLDataClip2(objects, umlListViewItems, diagrams); + setUMLDataClip2(objects, diagrams); } /** @@ -125,9 +129,6 @@ obj->saveToXMI(domDoc, objectsTag); } - QDomElement itemsTag = domDoc.createElement("umllistviewitems"); - xmiclip.appendChild(itemsTag); - setData("application/x-uml-clip1", domDoc.toString().toUtf8()); } @@ -135,8 +136,7 @@ * For use when the user selects UML Object and Diagrams * from the ListView to be copied */ -void UMLDragData::setUMLDataClip2(UMLObjectList& objects, UMLListViewItemList& umlListViewItems, - UMLViewList& diagrams) +void UMLDragData::setUMLDataClip2(UMLObjectList& objects, UMLViewList& diagrams) { QDomDocument domDoc; QDomElement xmiclip = domDoc.createElement("xmiclip"); @@ -158,13 +158,6 @@ view->umlScene()->saveToXMI(domDoc, viewsTag); } - QDomElement itemsTag = domDoc.createElement("umllistviewitems"); - xmiclip.appendChild(itemsTag); - - foreach(UMLListViewItem* item, umlListViewItems) { - item->saveToXMI(domDoc, itemsTag); - } - setData("application/x-uml-clip2", domDoc.toString().toUtf8()); } @@ -222,9 +215,6 @@ association->saveToXMI(domDoc, associationWidgetsTag); } - QDomElement itemsTag = domDoc.createElement("umllistviewitems"); - xmiclip.appendChild(itemsTag); - setData("application/x-uml-clip4", domDoc.toString().toUtf8()); QImage img = pngImage.toImage(); @@ -253,9 +243,6 @@ obj->saveToXMI(domDoc, objectsTag); } - QDomElement itemsTag = domDoc.createElement("umllistviewitems"); - xmiclip.appendChild(itemsTag); - setData("application/x-uml-clip5", domDoc.toString().toUtf8()); } @@ -267,7 +254,6 @@ */ bool UMLDragData::decodeClip1(const QMimeData* mimeData, UMLObjectList& objects) { - UMLDoc* doc = UMLApp::app()->document(); if (!mimeData->hasFormat("application/x-uml-clip1")) { return false; } @@ -281,7 +267,7 @@ int line; QDomDocument domDoc; if(!domDoc.setContent(xmiClip, false, &error, &line)) { - uWarning() << "Can not set content:" << error << " Line:" << line; + uWarning() << "Cannot set content:" << error << " Line:" << line; return false; } QDomNode xmiClipNode = domDoc.firstChild(); @@ -294,56 +280,9 @@ return false; } - UMLListView *listView = UMLApp::app()->listView(); - - //UMLObjects QDomNode objectsNode = xmiClipNode.firstChild(); - QDomNode objectElement = objectsNode.firstChild(); - QDomElement element = objectElement.toElement(); - if (element.isNull()) { - return false;//return ok as it means there is no umlobjects - } - UMLObject* pObject = 0; - while (!element.isNull()) { - pObject = 0; - QString type = element.tagName(); - if (type == "UML:Association") { - objectElement = objectElement.nextSibling(); - element = objectElement.toElement(); - continue; - } - pObject = Object_Factory::makeObjectFromXMI(type); - - if(!pObject) { - uWarning() << "Given wrong type of umlobject to create: " << type; - return false; - } - pObject->setInPaste(true); - if(!pObject->loadFromXMI(element)) { - uWarning() << "Failed to load object of type " << type << " from XMI"; - delete pObject; - return false; - } - pObject->setInPaste(false); - if (listView->startedCopy()) { - /**************************************************************** - * If the clone() methods called IDChangeLog::addIDChange(), - * we could do the following: - UMLObject *newObj = pObject->clone(); - delete pObject; - pObject = newObj; - * but since that's not currently the case we do: */ - if(!doc->assignNewIDs(pObject)) { - return false; - } - /****************************************************************/ - } - - pObject->resolveRef(); - - objects.append(pObject); - objectElement = objectElement.nextSibling(); - element = objectElement.toElement(); + if (!UMLDragData::decodeObjects(objectsNode, objects, false)) { + return false; } return true; @@ -354,8 +293,7 @@ * from the ListView to be copied, decodes Mime type = * "application/x-uml-clip2 */ -bool UMLDragData::decodeClip2(const QMimeData* mimeData, UMLObjectList& objects, - UMLListViewItemList& umlListViewItems, UMLViewList& diagrams) +bool UMLDragData::decodeClip2(const QMimeData* mimeData, UMLObjectList& objects, UMLViewList& diagrams) { if (!mimeData->hasFormat("application/x-uml-clip2")) { return false; @@ -370,7 +308,7 @@ int line; QDomDocument domDoc; if(!domDoc.setContent(xmiClip, false, &error, &line)) { - uWarning() << "Can not set content:" << error << " Line:" << line; + uWarning() << "Cannot set content:" << error << " Line:" << line; return false; } QDomNode xmiClipNode = domDoc.firstChild(); @@ -383,84 +321,18 @@ return false; } - //UMLObjects + // Load UMLObjects QDomNode objectsNode = xmiClipNode.firstChild(); - QDomNode objectElement = objectsNode.firstChild(); - QDomElement element = objectElement.toElement(); - if (element.isNull()) { - return false;//return ok as it means there is no umlobjects - } - UMLObject* pObject = 0; - while (!element.isNull()) { - pObject = 0; - QString type = element.tagName(); - if (type != "UML:Association") { - pObject = Object_Factory::makeObjectFromXMI(type); - - if(!pObject) { - uWarning() << "Given wrong type of umlobject to create:" << type; - return false; - } - if(!pObject->loadFromXMI(element)) { - uWarning() << "Failed to load object from XMI."; - return false; - } - objects.append(pObject); - } - objectElement = objectElement.nextSibling(); - element = objectElement.toElement(); + if (!UMLDragData::decodeObjects(objectsNode, objects, true)) { + return false; } - //UMLViews (diagrams) + // Load UMLViews (diagrams) QDomNode umlviewsNode = objectsNode.nextSibling(); - QDomNode diagramNode = umlviewsNode.firstChild(); - QDomElement diagramElement = diagramNode.toElement(); - if (diagramElement.isNull()) { - uWarning() << "No diagrams in XMI clip."; + if (!UMLDragData::decodeViews(umlviewsNode, diagrams)) { return false; } - UMLListView *listView = UMLApp::app()->listView(); - while (!diagramElement.isNull()) { - QString type = diagramElement.attribute("type", "0"); - Uml::DiagramType::Enum dt = Uml::DiagramType::fromInt(type.toInt()); - UMLListViewItem *parent = listView->findFolderForDiagram(dt); - if (parent == NULL) - return false; - UMLObject *po = parent->umlObject(); - if (po == NULL || po->baseType() != UMLObject::ot_Folder) { - uError() << "Bad parent for view."; - return false; - } - UMLFolder *f = static_cast(po); - UMLView* view = new UMLView(f); - view->umlScene()->loadFromXMI(diagramElement); - diagrams.append(view); - diagramNode = diagramNode.nextSibling(); - diagramElement = diagramNode.toElement(); - } - //listviewitems - QDomNode listItemNode = umlviewsNode.nextSibling(); - QDomNode listItems = listItemNode.firstChild(); - QDomElement listItemElement = listItems.toElement(); - if (listItemElement.isNull()) { - uWarning() << "No listitems in XMI clip."; - return false; - } - UMLListViewItem *currentItem = (UMLListViewItem*)listView->currentItem(); - while (!listItemElement.isNull()) { - UMLListViewItem* itemData; - if (currentItem) - itemData = new UMLListViewItem(currentItem); - else - itemData = new UMLListViewItem(listView); - if (itemData->loadFromXMI(listItemElement)) - umlListViewItems.append(itemData); - else - delete itemData; - listItems = listItems.nextSibling(); - listItemElement = listItems.toElement(); - } return true; } @@ -488,7 +360,7 @@ int line; QDomDocument domDoc; if(!domDoc.setContent(xmiClip, false, &error, &line)) { - uWarning() << "getClip3Type: Can not set content:" << error << " Line:" << line; + uWarning() << "getClip3Type: Cannot set content:" << error << " Line:" << line; return false; } QDomNode xmiClipNode = domDoc.firstChild(); @@ -528,12 +400,11 @@ } return true; } - -/** - * For use when the user selects UMLObjects from - * the ListView to be copied, decodes Mime * type = - * "application/x-uml-clip3 - */ + /** +- * For use when the user selects UMLObjects from +- * the ListView to be copied, decodes Mime * type = +- * "application/x-uml-clip3 +- */ bool UMLDragData::decodeClip3(const QMimeData* mimeData, UMLListViewItemList& umlListViewItems, const UMLListView* parentListView) { @@ -551,7 +422,7 @@ int line; QDomDocument domDoc; if(!domDoc.setContent(xmiClip, false, &error, &line)) { - uWarning() << "Can not set content:" << error << " Line:" << line; + uWarning() << "Cannot set content:" << error << " Line:" << line; return false; } QDomNode xmiClipNode = domDoc.firstChild(); @@ -578,6 +449,8 @@ QString type = listItemElement.attribute("type", "-1"); if (type == "-1") { uDebug() << "Type not found."; + listItems = listItems.nextSibling(); + listItemElement = listItems.toElement(); continue; } UMLListViewItem::ListViewType t = (UMLListViewItem::ListViewType)(type.toInt()); @@ -618,7 +491,7 @@ int line; QDomDocument domDoc; if(!domDoc.setContent(xmiClip, false, &error, &line)) { - uWarning() << "Can not set content:" << error << " Line:" << line; + uWarning() << "Cannot set content:" << error << " Line:" << line; return false; } QDomNode xmiClipNode = domDoc.firstChild(); @@ -632,40 +505,16 @@ } dType = Uml::DiagramType::fromInt(root.attribute("diagramtype", "0").toInt()); - - //UMLObjects QDomNode objectsNode = xmiClipNode.firstChild(); - QDomNode objectElement = objectsNode.firstChild(); - QDomElement element = objectElement.toElement(); - while (!element.isNull()) { - UMLObject* pObject = 0; - QString type = element.tagName(); - UMLDoc* doc = UMLApp::app()->document(); - Uml::ID::Type elmId = Uml::ID::fromString(element.attribute("xmi.id")); - pObject = doc->findObjectById(elmId); - - if (!pObject) { - pObject = Object_Factory::makeObjectFromXMI(type); - if (!pObject) { - uWarning() << "Given wrong type of umlobject to create: " << type; - return false; - } - - if (!pObject->loadFromXMI(element)) { - uWarning() << "Failed to load object from XMI."; - return false; - } - - doc->signalUMLObjectCreated(pObject); - } + // Load UMLObjects and do not fail if there are none in the clip + bool hasObjects = !objectsNode.firstChild().toElement().isNull(); - objects.append(pObject); - objectElement = objectElement.nextSibling(); - element = objectElement.toElement(); + if (hasObjects && !UMLDragData::decodeObjects(objectsNode, objects, true)) { + return false; } - //widgets + // Load widgets QDomNode widgetsNode = objectsNode.nextSibling(); QDomNode widgetNode = widgetsNode.firstChild(); QDomElement widgetElement = widgetNode.toElement(); @@ -674,19 +523,59 @@ return false; } + UMLDoc *doc = UMLApp::app()->document(); UMLView *view = UMLApp::app()->currentView(); UMLScene *scene = view->umlScene(); + while (!widgetElement.isNull()) { UMLWidget* widget = scene->loadWidgetFromXMI(widgetElement); - if (widget) + if (widget) { + // Generate a new unique 'local ID' so a second widget for the same + // UMLObject can be distinguished from the first widget + widget->setLocalID( + doc->assignNewID(widget->localID()) + ); + + // Add the widget to the UMLWidgetList for reference in + // UMLClipboard widgets.append(widget); + } else { + uWarning() << "Unable to paste widget" << widgetElement.tagName(); + } widgetNode = widgetNode.nextSibling(); widgetElement = widgetNode.toElement(); } - //AssociationWidgets + IDChangeLog* log = doc->changeLog(); + + // Make sure all object widgets are loaded before adding messages or + // preconditions + foreach (UMLWidget* widget, widgets) { + if (widget->baseType() == WidgetBase::wt_Object) { + executeCreateWidgetCommand(widget); + } + } + + // Now add all remaining widgets + foreach (UMLWidget* widget, widgets) { + if (widget->baseType() == WidgetBase::wt_Message) { + MessageWidget* message = dynamic_cast(widget); + message->resolveObjectWidget(log); + } + + if (widget->baseType() == WidgetBase::wt_Precondition) { + PreconditionWidget* precondition = dynamic_cast(widget); + precondition->resolveObjectWidget(log); + } + + if (widget->baseType() != WidgetBase::wt_Object) { + executeCreateWidgetCommand(widget); + } + } + + // Load AssociationWidgets QDomNode associationWidgetsNode = widgetsNode.nextSibling(); QDomNode associationWidgetNode = associationWidgetsNode.firstChild(); QDomElement associationWidgetElement = associationWidgetNode.toElement(); @@ -725,7 +614,7 @@ int line; QDomDocument domDoc; if(!domDoc.setContent(xmiClip, false, &error, &line)) { - uWarning() << "Can not set content:" << error << " Line:" << line; + uWarning() << "Cannot set content:" << error << " Line:" << line; return false; } QDomNode xmiClipNode = domDoc.firstChild(); @@ -763,6 +652,153 @@ } return true; +} + +/** + * Execute the CmdCreateWidget undo command + */ +void UMLDragData::executeCreateWidgetCommand(UMLWidget* widget) +{ + UMLApp::app()->executeCommand(new Uml::CmdCreateWidget(widget)); +} + +/** + * Decode UMLObjects from clip + */ +bool UMLDragData::decodeObjects(QDomNode& objectsNode, UMLObjectList& objects, bool skipIfObjectExists) +{ + UMLDoc* doc = UMLApp::app()->document(); + QDomNode objectElement = objectsNode.firstChild(); + QDomElement element = objectElement.toElement(); + if (element.isNull()) { + return false;//return ok as it means there is no umlobjects + } + UMLObject* pObject = 0; + while (!element.isNull()) { + pObject = 0; + QString type = element.tagName(); + Uml::ID::Type elmId = Uml::ID::fromString(element.attribute("xmi.id")); + QString stereotype = element.attribute("stereotype"); + + bool objectExists = (doc->findObjectById(elmId) != 0); + + // This happens when pasting clip4 (widgets): pasting widgets must + // not duplicate the UMLObjects, unless they don't exists (other + // instance of umbrello) + if (skipIfObjectExists && objectExists) { + objectElement = objectElement.nextSibling(); + element = objectElement.toElement(); + continue; + } + + // Remove ownedElements from containers: the clip already contains all children + // as a flat list (UMLClipboard::insertItemChildren) + if (type == "UML:Package" || + type == "UML:Class" || + type == "UML:Interface" || + type == "UML:Component") { + QDomNodeList list = element.childNodes(); + for (int i=(list.length() - 1); i>=0; i--) { + QDomNode child = list.at(i); + QString tagName = child.toElement().tagName(); + if (tagName == "UML:Namespace.ownedElement" || + tagName == "UML:Namespace.contents") { + element.removeChild(child); + } + } + } + + pObject = Object_Factory::makeObjectFromXMI(type, stereotype); + if(!pObject) { + uWarning() << "Given wrong type of umlobject to create: " << type; + return false; + } + + Uml::ID::Type oldParentId = Uml::ID::fromString( + element.attribute("namespace", "-1") + ); + + // Determine the parent package of the pasted object + UMLPackage* newParent = 0; + if (oldParentId != Uml::ID::None) { + Uml::ID::Type newParentId = doc->changeLog()->findNewID(oldParentId); + + if (newParentId == Uml::ID::None) { + // Fallback to parent ID before paste (folder was not pasted in + // this paste operation) + newParentId = oldParentId; + } + + newParent = static_cast(doc->findObjectById(newParentId)); + } + + if (newParent == 0) { + // Package is not in this clip, determine the parent based + // on the selected tree view item + newParent = Model_Utils::treeViewGetPackageFromCurrent(); + } + + pObject->setUMLPackage(newParent); + + // Note: element should not be used after calling loadFromXMI() because + // it can point to an arbitrary child node + if(!pObject->loadFromXMI(element)) { + uWarning() << "Failed to load object of type " << type << " from XMI"; + delete pObject; + return false; + } + + // Assign a new ID if the object already existed before this paste, + // this happens when pasting on listview items in the same document. + if (objectExists) { + pObject->setID( + doc->assignNewID(pObject->id()) + ); + } + + UMLApp::app()->executeCommand(new Uml::CmdCreateUMLObject(pObject)); + doc->signalUMLObjectCreated(pObject); + + objects.append(pObject); + objectElement = objectElement.nextSibling(); + element = objectElement.toElement(); + } + + return true; +} + +/** + * Decode views from clip + */ +bool UMLDragData::decodeViews(QDomNode& umlviewsNode, UMLViewList& diagrams) +{ + QDomNode diagramNode = umlviewsNode.firstChild(); + QDomElement diagramElement = diagramNode.toElement(); + if (diagramElement.isNull()) { + uWarning() << "No diagrams in XMI clip."; + return false; + } + UMLListView *listView = UMLApp::app()->listView(); + while (!diagramElement.isNull()) { + QString type = diagramElement.attribute("type", "0"); + Uml::DiagramType::Enum dt = Uml::DiagramType::fromInt(type.toInt()); + UMLListViewItem *parent = listView->findFolderForDiagram(dt); + if (parent == NULL) + return false; + UMLObject *po = parent->umlObject(); + if (po == NULL || po->baseType() != UMLObject::ot_Folder) { + uError() << "Bad parent for view."; + return false; + } + UMLFolder *f = static_cast(po); + UMLView* view = new UMLView(f); + view->umlScene()->loadFromXMI(diagramElement); + diagrams.append(view); + diagramNode = diagramNode.nextSibling(); + diagramElement = diagramNode.toElement(); + } + + return true; } /** diff -Nru umbrello-4.12.3/umbrello/clipboard/umldragdata.h umbrello-4.12.90/umbrello/clipboard/umldragdata.h --- umbrello-4.12.3/umbrello/clipboard/umldragdata.h 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/clipboard/umldragdata.h 2014-03-05 15:04:09.000000000 +0000 @@ -22,8 +22,8 @@ #include #include -class UMLListView; class UMLClassifier; +class UMLListView; class QPixmap; /** @@ -40,8 +40,7 @@ explicit UMLDragData(UMLObjectList& Objects, QWidget* dragSource = 0); - UMLDragData(UMLObjectList &Objects, UMLListViewItemList& UMLListViewItems, - UMLViewList& Diagrams, QWidget * dragSource = 0); + UMLDragData(UMLObjectList &Objects, UMLViewList& Diagrams, QWidget * dragSource = 0); explicit UMLDragData(UMLListViewItemList& UMLListViewItems, QWidget* dragSource = 0); @@ -56,13 +55,11 @@ static bool decodeClip1(const QMimeData* mimeData, UMLObjectList& objects); - static bool decodeClip2(const QMimeData* mimeData, UMLObjectList& objects, - UMLListViewItemList& umlListViewItems, - UMLViewList& diagrams); + static bool decodeClip2(const QMimeData* mimeData, UMLObjectList& objects, UMLViewList& diagrams); static bool decodeClip3(const QMimeData* mimeData, - UMLListViewItemList& umlListViewItems, - const UMLListView* parentListView=0); + UMLListViewItemList& umlListViewItems, + const UMLListView* parentListView=0); struct LvTypeAndID { UMLListViewItem::ListViewType type; @@ -88,8 +85,7 @@ void setUMLDataClip1(UMLObjectList& Objects); - void setUMLDataClip2(UMLObjectList& Objects, UMLListViewItemList& UMLListViewItems, - UMLViewList& Diagrams); + void setUMLDataClip2(UMLObjectList& Objects, UMLViewList& Diagrams); void setUMLDataClip3(UMLListViewItemList& UMLListViewItems); @@ -100,6 +96,12 @@ void setUMLDataClip5(UMLObjectList& Objects); + static void executeCreateWidgetCommand(UMLWidget* widget); + + static bool decodeObjects(QDomNode& objectsNode, UMLObjectList& objects, + bool skipIfObjectExists = false); + + static bool decodeViews(QDomNode& umlviewsNode, UMLViewList& diagrams); }; #endif diff -Nru umbrello-4.12.3/umbrello/CMakeLists.txt umbrello-4.12.90/umbrello/CMakeLists.txt --- umbrello-4.12.3/umbrello/CMakeLists.txt 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/CMakeLists.txt 2014-03-05 15:04:09.000000000 +0000 @@ -13,9 +13,9 @@ #add_definitions(-DDEBUG_PRINTING) # umlview #add_definitions(-DVERBOSE_DEBUGGING) # listpopupmenu, association, petaltree2uml, # umlobject, umldoc, classifierlistpage - -# Some Boost require exceptions -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}") +if(UNIX) + add_definitions(-D_GLIBCXX_PERMIT_BACKWARD_HASH) +endif() include_directories( ${LIBXML2_INCLUDE_DIR} @@ -50,7 +50,8 @@ ${CMAKE_CURRENT_SOURCE_DIR}/docgenerators/ ${CMAKE_CURRENT_SOURCE_DIR}/refactoring/ ${CMAKE_CURRENT_SOURCE_DIR}/widgets/ - ${Boost_INCLUDE_DIR} + ${CMAKE_SOURCE_DIR}/lib/cppparser/ + ${CMAKE_SOURCE_DIR}/lib/interfaces/ ) set(libdebug_SRCS @@ -189,6 +190,7 @@ dialogs/codetextedit.cpp dialogs/codetexthighlighter.cpp dialogs/defaultcodegenpolicypage.cpp + dialogs/diagrampropertiespage.cpp dialogs/diagramprintpage.cpp dialogs/dialog_utils.cpp dialogs/dialogbase.cpp @@ -270,16 +272,19 @@ list(APPEND libcodeimport_SRCS codeimport/cppimport.cpp ) + set(libkdevcppparser_SRCS - codeimport/kdevcppparser/ast.cpp - codeimport/kdevcppparser/driver.cpp - codeimport/kdevcppparser/errors.cpp - codeimport/kdevcppparser/lexer.cpp - codeimport/kdevcppparser/lookup.cpp - codeimport/kdevcppparser/parser.cpp - codeimport/kdevcppparser/preprocesslexer.cpp - codeimport/kdevcppparser/tree_parser.cpp - codeimport/kdevcppparser/ast_utils.cpp + ${CMAKE_SOURCE_DIR}/lib/cppparser/ast.cpp + ${CMAKE_SOURCE_DIR}/lib/cppparser/ast_utils.cpp + ${CMAKE_SOURCE_DIR}/lib/cppparser/cachemanager.cpp + ${CMAKE_SOURCE_DIR}/lib/cppparser/driver.cpp + ${CMAKE_SOURCE_DIR}/lib/cppparser/errors.cpp + ${CMAKE_SOURCE_DIR}/lib/cppparser/lexer.cpp + ${CMAKE_SOURCE_DIR}/lib/cppparser/lexercache.cpp + ${CMAKE_SOURCE_DIR}/lib/cppparser/lookup.cpp + ${CMAKE_SOURCE_DIR}/lib/cppparser/parser.cpp + ${CMAKE_SOURCE_DIR}/lib/cppparser/tree_parser.cpp + ${CMAKE_SOURCE_DIR}/lib/interfaces/hashedstring.cpp codeimport/kdevcppparser/cpptree2uml.cpp ) @@ -291,20 +296,28 @@ set(libcmds_SRCS cmds/cmd_createDiagram.cpp + cmds/cmd_removeDiagram.cpp cmds/cmd_handleRename.cpp - cmds/cmd_moveWidget.cpp - cmds/cmd_resizeWidget.cpp cmds/cmd_setStereotype.cpp cmds/cmd_setVisibility.cpp + cmds/cmd_baseObjectCommand.cpp cmds/generic/cmd_createUMLObject.cpp + cmds/generic/cmd_removeUMLObject.cpp cmds/generic/cmd_renameUMLObject.cpp - cmds/widget/cmd_changeFontSelection.cpp + cmds/widget/cmd_baseWidgetCommand.cpp + cmds/widget/cmd_moveWidget.cpp + cmds/widget/cmd_resizeWidget.cpp + cmds/widget/cmd_removeWidget.cpp + cmds/widget/cmd_changeFont.cpp cmds/widget/cmd_changeTextColor.cpp cmds/widget/cmd_changeLineColor.cpp + cmds/widget/cmd_changeLineWidth.cpp cmds/widget/cmd_changeFillColor.cpp + cmds/widget/cmd_changeUseFillColor.cpp cmds/widget/cmd_changeMultiplicity.cpp + cmds/widget/cmd_changeVisualProperty.cpp cmds/widget/cmd_createWidget.cpp cmds/widget/cmd_setName.cpp cmds/widget/cmd_setTxt.cpp diff -Nru umbrello-4.12.3/umbrello/cmds/cmd_baseObjectCommand.cpp umbrello-4.12.90/umbrello/cmds/cmd_baseObjectCommand.cpp --- umbrello-4.12.3/umbrello/cmds/cmd_baseObjectCommand.cpp 1970-01-01 00:00:00.000000000 +0000 +++ umbrello-4.12.90/umbrello/cmds/cmd_baseObjectCommand.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -0,0 +1,48 @@ +/*************************************************************************** + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * copyright (C) 2007-2013 * + * Umbrello UML Modeller Authors * + ***************************************************************************/ + +#include "cmd_baseObjectCommand.h" + +// app includes +#include "uml.h" +#include "umldoc.h" +#include "umlobject.h" + +// kde includes +#include + +namespace Uml +{ + CmdBaseObjectCommand::CmdBaseObjectCommand(UMLObject* object) + { + setObject(object); + } + + CmdBaseObjectCommand::~CmdBaseObjectCommand() + { + } + + void CmdBaseObjectCommand::setObject(UMLObject* object) + { + Q_ASSERT(object); + + m_objectId = object->id(); + } + + UMLObject* CmdBaseObjectCommand::object() + { + UMLDoc *doc = UMLApp::app()->document(); + UMLObject *umlObject = doc->findObjectById(m_objectId); + + //Q_ASSERT(umlObject); + + return umlObject; + } +} diff -Nru umbrello-4.12.3/umbrello/cmds/cmd_baseObjectCommand.h umbrello-4.12.90/umbrello/cmds/cmd_baseObjectCommand.h --- umbrello-4.12.3/umbrello/cmds/cmd_baseObjectCommand.h 1970-01-01 00:00:00.000000000 +0000 +++ umbrello-4.12.90/umbrello/cmds/cmd_baseObjectCommand.h 2014-03-05 15:04:09.000000000 +0000 @@ -0,0 +1,36 @@ +/*************************************************************************** + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * copyright (C) 2002-2013 * + * Umbrello UML Modeller Authors * + ***************************************************************************/ + +#ifndef CMD_BASEOBJECTCOMMAND_H +#define CMD_BASEOBJECTCOMMAND_H + +#include "basictypes.h" + +#include + +class UMLObject; + +namespace Uml +{ + class CmdBaseObjectCommand : public QUndoCommand + { + public: + explicit CmdBaseObjectCommand(UMLObject *object); + virtual ~CmdBaseObjectCommand(); + + protected: + Uml::ID::Type m_objectId; + + void setObject(UMLObject* object); + UMLObject* object(); + }; +} + +#endif // CMD_BASEOBJECTCOMMAND_H diff -Nru umbrello-4.12.3/umbrello/cmds/cmd_createDiagram.cpp umbrello-4.12.90/umbrello/cmds/cmd_createDiagram.cpp --- umbrello-4.12.3/umbrello/cmds/cmd_createDiagram.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/cmds/cmd_createDiagram.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -29,6 +29,8 @@ { QString msg = i18n("Create diagram %1: %2", DiagramType::toString(type), name); setText(msg); + + m_sceneId = Uml::ID::None; } CmdCreateDiagram::~CmdCreateDiagram() @@ -40,16 +42,20 @@ if (!m_pUMLDoc->findView(m_type, m_name, true)) { Uml::ModelType::Enum modelType = Model_Utils::convert_DT_MT(m_type); UMLFolder* folder = m_pUMLDoc->rootFolder(modelType); - m_pUMLView = m_pUMLDoc->createDiagram(folder, m_type, m_name); + m_pUMLView = m_pUMLDoc->createDiagram(folder, m_type, m_name, m_sceneId); } + + // Remember the scene-ID, it might be auto generated. The ID must + // not change after undo/redo because other commands may try to + // lookup the diagram later. + m_sceneId = m_pUMLView->umlScene()->ID(); } void CmdCreateDiagram::undo() { -//:TODO: commented for preventing crash because of invalid pointers -// if (m_pUMLView) { -// m_pUMLDoc->removeDiagram(m_pUMLView->umlScene()->ID()); -// } + if (m_pUMLView) { + m_pUMLDoc->removeDiagramCmd(m_sceneId); + } } } diff -Nru umbrello-4.12.3/umbrello/cmds/cmd_createDiagram.h umbrello-4.12.90/umbrello/cmds/cmd_createDiagram.h --- umbrello-4.12.3/umbrello/cmds/cmd_createDiagram.h 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/cmds/cmd_createDiagram.h 2014-03-05 15:04:09.000000000 +0000 @@ -34,6 +34,7 @@ Uml::DiagramType::Enum m_type; UMLDoc* m_pUMLDoc; UMLView* m_pUMLView; + Uml::ID::Type m_sceneId; }; } diff -Nru umbrello-4.12.3/umbrello/cmds/cmd_moveWidget.cpp umbrello-4.12.90/umbrello/cmds/cmd_moveWidget.cpp --- umbrello-4.12.3/umbrello/cmds/cmd_moveWidget.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/cmds/cmd_moveWidget.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,63 +0,0 @@ -/*************************************************************************** - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * copyright (C) 2002-2013 * - * Umbrello UML Modeller Authors * - ***************************************************************************/ - -#include "cmd_moveWidget.h" - -// app includes -#include "umlscene.h" -#include "umlwidget.h" - -#include - -namespace Uml -{ - - CmdMoveWidget::CmdMoveWidget(UMLWidget *widget) - : QUndoCommand(), - m_widget(widget) - { - Q_ASSERT(widget != 0); - setText(i18n("Move widget : %1", widget->name())); - m_pos = widget->pos(); - m_posOld = widget->startMovePosition(); - } - - CmdMoveWidget::~CmdMoveWidget() - { - } - - void CmdMoveWidget::redo() - { - UMLScene* scene = m_widget->umlScene(); - if (scene && scene->widgetOnDiagram(m_widget->id())) { - m_widget->setPos(m_pos); - m_widget->updateGeometry(); - } - } - - void CmdMoveWidget::undo() - { - UMLScene* scene = m_widget->umlScene(); - if (scene && scene->widgetOnDiagram(m_widget->id())) { - m_widget->setPos(m_posOld); - m_widget->updateGeometry(); - } - } - -// bool CmdMoveWidget::mergeWith(const QUndoCommand* other) -// { -// const CmdMoveWidget* otherCmd = static_cast(other); -// if (m_widgetCtrl != otherCmd->m_widgetCtrl) -// return false; -// m_x = otherCmd->m_x; -// m_y = otherCmd->m_y; -// return true; -// } -} diff -Nru umbrello-4.12.3/umbrello/cmds/cmd_moveWidget.h umbrello-4.12.90/umbrello/cmds/cmd_moveWidget.h --- umbrello-4.12.3/umbrello/cmds/cmd_moveWidget.h 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/cmds/cmd_moveWidget.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,40 +0,0 @@ -/*************************************************************************** - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * copyright (C) 2002-2013 * - * Umbrello UML Modeller Authors * - ***************************************************************************/ - -#ifndef CMD_MOVEWIDGET_H -#define CMD_MOVEWIDGET_H - -#include -#include - -class UMLWidget; - -namespace Uml -{ - class CmdMoveWidget : public QUndoCommand - { - public: - explicit CmdMoveWidget(UMLWidget* widget); - ~CmdMoveWidget(); - - void redo(); - void undo(); - - // bool mergeWith(const QUndoCommand* other); - - private: - UMLWidget* m_widget; - QPointF m_pos; - QPointF m_posOld; - - }; -} - -#endif diff -Nru umbrello-4.12.3/umbrello/cmds/cmd_removeDiagram.cpp umbrello-4.12.90/umbrello/cmds/cmd_removeDiagram.cpp --- umbrello-4.12.3/umbrello/cmds/cmd_removeDiagram.cpp 1970-01-01 00:00:00.000000000 +0000 +++ umbrello-4.12.90/umbrello/cmds/cmd_removeDiagram.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -0,0 +1,65 @@ +/*************************************************************************** + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * copyright (C) 2012-2013 * + * Umbrello UML Modeller Authors * + ***************************************************************************/ + +#include "cmd_removeDiagram.h" + +#include "basictypes.h" +#include "uml.h" +#include "umldoc.h" +#include "umlscene.h" +#include "umlview.h" + +#include + +namespace Uml +{ + + CmdRemoveDiagram::CmdRemoveDiagram(UMLFolder* folder, + Uml::DiagramType::Enum type, + const QString& name, + Uml::ID::Type id) + : QUndoCommand(), + m_folder(folder), + m_type(type), + m_name(name), + m_sceneId(id) + { + UMLScene* scene = UMLApp::app()->document()->findView(id)->umlScene(); + + QString msg = i18n("Remove diagram %1", scene->name()); + setText(msg); + + // Save diagram XMI for undo + QDomDocument doc; + QDomElement container = doc.createElement("diagram"); + scene->saveToXMI(doc, container); + + // The first child element contains the diagram XMI + m_element = container.firstChild().toElement(); + } + + CmdRemoveDiagram::~CmdRemoveDiagram() + { + } + + void CmdRemoveDiagram::redo() + { + UMLApp::app()->document()->removeDiagramCmd(m_sceneId); + } + + void CmdRemoveDiagram::undo() + { + UMLDoc* doc = UMLApp::app()->document(); + UMLView* view = doc->createDiagram(m_folder, m_type, m_name, m_sceneId); + + view->umlScene()->loadFromXMI(m_element); + } + +} diff -Nru umbrello-4.12.3/umbrello/cmds/cmd_removeDiagram.h umbrello-4.12.90/umbrello/cmds/cmd_removeDiagram.h --- umbrello-4.12.3/umbrello/cmds/cmd_removeDiagram.h 1970-01-01 00:00:00.000000000 +0000 +++ umbrello-4.12.90/umbrello/cmds/cmd_removeDiagram.h 2014-03-05 15:04:09.000000000 +0000 @@ -0,0 +1,46 @@ +/*************************************************************************** + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * copyright (C) 2012-2013 * + * Umbrello UML Modeller Authors * + ***************************************************************************/ + +#ifndef CMD_REMOVE_DIAGRAM_H +#define CMD_REMOVE_DIAGRAM_H + +#include "basictypes.h" + +#include +#include + +class UMLDoc; +class UMLView; +class UMLFolder; + +namespace Uml +{ + class CmdRemoveDiagram : public QUndoCommand + { + public: + explicit CmdRemoveDiagram(UMLFolder* folder, + Uml::DiagramType::Enum type, + const QString& name, + Uml::ID::Type id); + ~CmdRemoveDiagram(); + + void redo(); + void undo(); + + private: + UMLFolder* m_folder; + Uml::DiagramType::Enum m_type; + QString m_name; + Uml::ID::Type m_sceneId; + QDomElement m_element; + }; +} + +#endif diff -Nru umbrello-4.12.3/umbrello/cmds/cmd_resizeWidget.cpp umbrello-4.12.90/umbrello/cmds/cmd_resizeWidget.cpp --- umbrello-4.12.3/umbrello/cmds/cmd_resizeWidget.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/cmds/cmd_resizeWidget.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,52 +0,0 @@ -/*************************************************************************** - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * copyright (C) 2002-2013 * - * Umbrello UML Modeller Authors * - ***************************************************************************/ - -#include "cmd_resizeWidget.h" - -// app includes -#include "umlscene.h" -#include "umlwidget.h" - -#include - -namespace Uml -{ - - CmdResizeWidget::CmdResizeWidget(UMLWidget *widget) - : QUndoCommand(), - m_widget(widget) - { - Q_ASSERT(widget != 0); - setText(i18n("Resize widget : %1", widget->name())); - m_size = QSizeF(widget->width(), widget->height()); - m_sizeOld = widget->startResizeSize(); - } - - CmdResizeWidget::~CmdResizeWidget() - { - } - - void CmdResizeWidget::redo() - { - UMLScene* scene = m_widget->umlScene(); - if (scene && scene->widgetOnDiagram(m_widget->id())) { - m_widget->setSize(m_size); - } - } - - void CmdResizeWidget::undo() - { - UMLScene* scene = m_widget->umlScene(); - if (scene && scene->widgetOnDiagram(m_widget->id())) { - m_widget->setSize(m_sizeOld); - } - } - -} diff -Nru umbrello-4.12.3/umbrello/cmds/cmd_resizeWidget.h umbrello-4.12.90/umbrello/cmds/cmd_resizeWidget.h --- umbrello-4.12.3/umbrello/cmds/cmd_resizeWidget.h 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/cmds/cmd_resizeWidget.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,37 +0,0 @@ -/*************************************************************************** - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * copyright (C) 2002-2013 * - * Umbrello UML Modeller Authors * - ***************************************************************************/ - -#ifndef CMD_RESIZEWIDGET_H -#define CMD_RESIZEWIDGET_H - -#include -#include - -class UMLWidget; - -namespace Uml -{ - class CmdResizeWidget : public QUndoCommand - { - public: - explicit CmdResizeWidget(UMLWidget* widget); - ~CmdResizeWidget(); - - void redo(); - void undo(); - - private: - UMLWidget* m_widget; - QSizeF m_size; - QSizeF m_sizeOld; - }; -} - -#endif diff -Nru umbrello-4.12.3/umbrello/cmds/cmd_setStereotype.cpp umbrello-4.12.90/umbrello/cmds/cmd_setStereotype.cpp --- umbrello-4.12.3/umbrello/cmds/cmd_setStereotype.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/cmds/cmd_setStereotype.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -19,7 +19,8 @@ { CmdSetStereotype::CmdSetStereotype(UMLObject * obj, const QString& stereo) - : m_stereo(stereo), m_umlObject(obj) + : CmdBaseObjectCommand(obj), + m_stereo(stereo) { m_oldStereo = obj->stereotype(); setText(i18n("Set stereotype : %1 to %2", m_oldStereo, stereo)); @@ -31,12 +32,16 @@ void CmdSetStereotype::redo() { - m_umlObject->setStereotypeCmd(m_stereo); + UMLObject *umlObject = object(); + if (umlObject) + umlObject->setStereotypeCmd(m_stereo); } void CmdSetStereotype::undo() { - m_umlObject->setStereotypeCmd(m_oldStereo); + UMLObject *umlObject = object(); + if (umlObject) + umlObject->setStereotypeCmd(m_oldStereo); } } diff -Nru umbrello-4.12.3/umbrello/cmds/cmd_setStereotype.h umbrello-4.12.90/umbrello/cmds/cmd_setStereotype.h --- umbrello-4.12.3/umbrello/cmds/cmd_setStereotype.h 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/cmds/cmd_setStereotype.h 2014-03-05 15:04:09.000000000 +0000 @@ -11,13 +11,11 @@ #ifndef CMD_SETSTEREOTYPE_H #define CMD_SETSTEREOTYPE_H -#include - -class UMLObject; +#include "cmd_baseObjectCommand.h" namespace Uml { - class CmdSetStereotype : public QUndoCommand + class CmdSetStereotype : public CmdBaseObjectCommand { public: CmdSetStereotype(UMLObject * obj, const QString& stereo); @@ -29,7 +27,6 @@ private: QString m_stereo; QString m_oldStereo; - UMLObject* m_umlObject; }; } diff -Nru umbrello-4.12.3/umbrello/cmds/cmd_setVisibility.cpp umbrello-4.12.90/umbrello/cmds/cmd_setVisibility.cpp --- umbrello-4.12.3/umbrello/cmds/cmd_setVisibility.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/cmds/cmd_setVisibility.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -11,6 +11,8 @@ #include "cmd_setVisibility.h" // app includes +#include "uml.h" +#include "umldoc.h" #include "umlobject.h" #include @@ -19,7 +21,8 @@ { CmdSetVisibility::CmdSetVisibility(UMLObject * obj, Visibility::Enum visibility) - : m_visibility(visibility), m_umlObject(obj) + : CmdBaseObjectCommand(obj), + m_visibility(visibility) { setText(i18n("Change visibility : %1", obj->name())); m_oldVisibility = obj->visibility(); @@ -31,12 +34,16 @@ void CmdSetVisibility::redo() { - m_umlObject->setVisibilityCmd(m_visibility); + UMLObject *umlObject = object(); + if (umlObject) + umlObject->setVisibilityCmd(m_visibility); } void CmdSetVisibility::undo() { - m_umlObject->setVisibilityCmd(m_oldVisibility); + UMLObject *umlObject = object(); + if (umlObject) + umlObject->setVisibilityCmd(m_oldVisibility); } } diff -Nru umbrello-4.12.3/umbrello/cmds/cmd_setVisibility.h umbrello-4.12.90/umbrello/cmds/cmd_setVisibility.h --- umbrello-4.12.3/umbrello/cmds/cmd_setVisibility.h 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/cmds/cmd_setVisibility.h 2014-03-05 15:04:09.000000000 +0000 @@ -11,15 +11,11 @@ #ifndef CMD_SETVISIBILITY_H #define CMD_SETVISIBILITY_H -#include - -#include "basictypes.h" - -class UMLObject; +#include "cmd_baseObjectCommand.h" namespace Uml { - class CmdSetVisibility : public QUndoCommand + class CmdSetVisibility : public CmdBaseObjectCommand { public: CmdSetVisibility(UMLObject* obj, Uml::Visibility::Enum visibility); @@ -31,7 +27,6 @@ private: Uml::Visibility::Enum m_oldVisibility; Uml::Visibility::Enum m_visibility; - UMLObject* m_umlObject; }; } diff -Nru umbrello-4.12.3/umbrello/cmds/generic/cmd_createUMLObject.cpp umbrello-4.12.90/umbrello/cmds/generic/cmd_createUMLObject.cpp --- umbrello-4.12.3/umbrello/cmds/generic/cmd_createUMLObject.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/cmds/generic/cmd_createUMLObject.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -12,13 +12,9 @@ // app includes #include "debug_utils.h" -#include "object_factory.h" #include "package.h" #include "uml.h" #include "umldoc.h" -#include "umlscene.h" -#include "umlview.h" -#include "widget_factory.h" // kde includes #include @@ -31,18 +27,14 @@ */ CmdCreateUMLObject::CmdCreateUMLObject(UMLObject* o) : QUndoCommand(), - m_obj(o) + m_obj(o), + m_skipSignal(true) { - if (m_obj) { - setText(i18n("Create UML object : %1", m_obj->fullyQualifiedName())); - m_package = m_obj->umlPackage(); - m_type = m_obj->baseType(); - m_name = m_obj->name(); - m_element.clear(); - } - else { - setText(i18n("Create UML object : CANNOT DO THAT, OBJECT IS NULL!")); - } + setText(i18n("Create UML object : %1", m_obj->fullyQualifiedName())); + + m_package = m_obj->umlPackage(); + m_type = m_obj->baseType(); + m_name = m_obj->name(); } /** @@ -57,43 +49,23 @@ */ void CmdCreateUMLObject::redo() { - bool success = true; -//:TODO: unfinished idea for preventing crash because of invalid pointers -// if (!m_element.isNull()) { -// m_obj = Object_Factory::createUMLObject(m_type, m_name, m_package, false); -// success = m_obj->loadFromXMI(m_element); -// if (success) { -// uDebug() << m_obj; -// UMLScene* scene = UMLApp::app()->currentView()->umlScene(); -// if (scene) { -// UMLWidget* widget = scene->findWidget(m_obj->id()); -// if (!widget) { -// UMLWidget* newWidget = Widget_Factory::createWidget(scene, m_obj); -// if (newWidget) { -// scene->setupNewWidget(newWidget); // vielleicht nicht so gut - code wie bei UMLScene::slotObjectCreated -// } -// } -// } -// else { -// uDebug() << "There is no scene!"; -// } -// } -// else { -// uDebug() << "UMLObject was not loaded from XMI structure!"; -// } -// } - - if (success) { - // This object was removed from it's package when it was deleted - // so add it back to it's package (if it belonged to one) - if (m_package) { + // This object was removed from it's package when it was deleted + // so add it back to it's package (if it belonged to one) + if (m_package) { + if (m_package->baseType() != UMLObject::ot_Association) { // add this object to its parent package m_package->addObject(m_obj); - - } else { - // object does not belong to any package } + else + uError() << "Try to use an unsuppoprted Association as parent"; + } + // The first call to redo, the object was created and signalled by the + // caller (umlscene). On subsequent calls we use the "umlobject created" + // signal to update Umbrello with the re-added object. + if (m_skipSignal) { + m_skipSignal = false; + } else { UMLDoc *doc = UMLApp::app()->document(); doc->signalUMLObjectCreated(m_obj); } @@ -104,12 +76,8 @@ */ void CmdCreateUMLObject::undo() { -//:TODO: commented for preventing crash because of invalid pointers -// QDomDocument qDoc; -// m_obj->saveToXMI(qDoc, m_element); - -// UMLDoc *doc = UMLApp::app()->document(); -// doc->removeUMLObject(m_obj); + UMLDoc *doc = UMLApp::app()->document(); + doc->removeUMLObject(m_obj); } } diff -Nru umbrello-4.12.3/umbrello/cmds/generic/cmd_createUMLObject.h umbrello-4.12.90/umbrello/cmds/generic/cmd_createUMLObject.h --- umbrello-4.12.3/umbrello/cmds/generic/cmd_createUMLObject.h 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/cmds/generic/cmd_createUMLObject.h 2014-03-05 15:04:09.000000000 +0000 @@ -33,7 +33,7 @@ UMLPackage *m_package; UMLObject::ObjectType m_type; QString m_name; - QDomElement m_element; + bool m_skipSignal; }; } diff -Nru umbrello-4.12.3/umbrello/cmds/generic/cmd_removeUMLObject.cpp umbrello-4.12.90/umbrello/cmds/generic/cmd_removeUMLObject.cpp --- umbrello-4.12.3/umbrello/cmds/generic/cmd_removeUMLObject.cpp 1970-01-01 00:00:00.000000000 +0000 +++ umbrello-4.12.90/umbrello/cmds/generic/cmd_removeUMLObject.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -0,0 +1,59 @@ +/*************************************************************************** + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * copyright (C) 2002-2013 * + * Umbrello UML Modeller Authors * + ***************************************************************************/ + +#include "cmd_removeUMLObject.h" + +// app includes +#include "uml.h" +#include "umldoc.h" + +// kde includes +#include + +namespace Uml +{ + + /** + * Constructor. + */ + CmdRemoveUMLObject::CmdRemoveUMLObject(UMLObject* o) + : QUndoCommand(), + m_obj(o) + { + setText(i18n("Remove UML object : %1", m_obj->fullyQualifiedName())); + } + + /** + * Destructor. + */ + CmdRemoveUMLObject::~CmdRemoveUMLObject() + { + } + + /** + * Remove the UMLObject. + */ + void CmdRemoveUMLObject::redo() + { + UMLDoc *doc = UMLApp::app()->document(); + doc->removeUMLObject(m_obj); + } + + /** + * Suppress the UMLObject. + */ + void CmdRemoveUMLObject::undo() + { + UMLDoc *doc = UMLApp::app()->document(); + doc->addUMLObject(m_obj); + doc->signalUMLObjectCreated(m_obj); + } + +} diff -Nru umbrello-4.12.3/umbrello/cmds/generic/cmd_removeUMLObject.h umbrello-4.12.90/umbrello/cmds/generic/cmd_removeUMLObject.h --- umbrello-4.12.3/umbrello/cmds/generic/cmd_removeUMLObject.h 1970-01-01 00:00:00.000000000 +0000 +++ umbrello-4.12.90/umbrello/cmds/generic/cmd_removeUMLObject.h 2014-03-05 15:04:09.000000000 +0000 @@ -0,0 +1,33 @@ +/*************************************************************************** + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * copyright (C) 2002-2013 * + * Umbrello UML Modeller Authors * + ***************************************************************************/ + +#ifndef CMD_REMOVE_UMLOBJECT_H +#define CMD_REMOVE_UMLOBJECT_H + +#include "umlobject.h" +#include + +namespace Uml +{ + class CmdRemoveUMLObject : public QUndoCommand + { + public: + explicit CmdRemoveUMLObject(UMLObject* o); + ~CmdRemoveUMLObject(); + + void redo(); + void undo(); + + private: + UMLObject *m_obj; + }; +} + +#endif diff -Nru umbrello-4.12.3/umbrello/cmds/widget/cmd_baseWidgetCommand.cpp umbrello-4.12.90/umbrello/cmds/widget/cmd_baseWidgetCommand.cpp --- umbrello-4.12.3/umbrello/cmds/widget/cmd_baseWidgetCommand.cpp 1970-01-01 00:00:00.000000000 +0000 +++ umbrello-4.12.90/umbrello/cmds/widget/cmd_baseWidgetCommand.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -0,0 +1,78 @@ +/*************************************************************************** + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * copyright (C) 2007-2013 * + * Umbrello UML Modeller Authors * + ***************************************************************************/ + +#include "cmd_baseWidgetCommand.h" + +// app includes +#include "messagewidget.h" +#include "uml.h" +#include "umldoc.h" +#include "umlscene.h" +#include "umlview.h" +#include "umlwidget.h" + +// kde includes +#include + +namespace Uml +{ + CmdBaseWidgetCommand::CmdBaseWidgetCommand(UMLWidget* widget) + { + setWidget(widget); + } + + CmdBaseWidgetCommand::~CmdBaseWidgetCommand() + { + } + + void CmdBaseWidgetCommand::setWidget(UMLWidget* widget) + { + Q_ASSERT(widget); + + m_widgetId = widget->localID(); + m_sceneId = widget->umlScene()->ID(); + } + + UMLScene* CmdBaseWidgetCommand::scene() + { + UMLView* umlView = UMLApp::app()->document()->findView(m_sceneId); + + Q_ASSERT(umlView); + + return umlView->umlScene(); + } + + UMLWidget* CmdBaseWidgetCommand::widget() + { + UMLWidget* umlWidget = scene()->findWidgetByLocalId(m_widgetId); + + Q_ASSERT(umlWidget); + + return umlWidget; + } + + /** + * Add widget to scene + * + * @param UMLWidget* widget + */ + void CmdBaseWidgetCommand::addWidgetToScene(UMLWidget* umlWidget) + { + if (umlWidget->baseType() == WidgetBase::wt_Message) { + scene()->messageList().append( + dynamic_cast(umlWidget) + ); + } else { + scene()->widgetList().append(umlWidget); + } + + umlWidget->activate(); + } +} diff -Nru umbrello-4.12.3/umbrello/cmds/widget/cmd_baseWidgetCommand.h umbrello-4.12.90/umbrello/cmds/widget/cmd_baseWidgetCommand.h --- umbrello-4.12.3/umbrello/cmds/widget/cmd_baseWidgetCommand.h 1970-01-01 00:00:00.000000000 +0000 +++ umbrello-4.12.90/umbrello/cmds/widget/cmd_baseWidgetCommand.h 2014-03-05 15:04:09.000000000 +0000 @@ -0,0 +1,40 @@ +/*************************************************************************** + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * copyright (C) 2002-2013 * + * Umbrello UML Modeller Authors * + ***************************************************************************/ + +#ifndef CMD_BASEWIDGETCOMMAND_H +#define CMD_BASEWIDGETCOMMAND_H + +#include "basictypes.h" + +#include + +class UMLScene; +class UMLWidget; + +namespace Uml +{ + class CmdBaseWidgetCommand : public QUndoCommand + { + public: + explicit CmdBaseWidgetCommand(UMLWidget* widget); + virtual ~CmdBaseWidgetCommand(); + + protected: + Uml::ID::Type m_sceneId; + Uml::ID::Type m_widgetId; + + void setWidget(UMLWidget* widget); + void addWidgetToScene(UMLWidget* widget); + UMLWidget* widget(); + UMLScene* scene(); + }; +} + +#endif // CMD_BASEWIDGETCOMMAND_H diff -Nru umbrello-4.12.3/umbrello/cmds/widget/cmd_changeFillColor.cpp umbrello-4.12.90/umbrello/cmds/widget/cmd_changeFillColor.cpp --- umbrello-4.12.3/umbrello/cmds/widget/cmd_changeFillColor.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/cmds/widget/cmd_changeFillColor.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -12,7 +12,6 @@ #include "cmd_changeFillColor.h" -#include "umlscene.h" #include "umlwidget.h" // kde includes @@ -20,13 +19,13 @@ namespace Uml { - CmdChangeFillColor::CmdChangeFillColor(UMLWidget *w, const QColor& col) - : m_widget(w), + CmdChangeFillColor::CmdChangeFillColor(UMLWidget* widget, const QColor& col) + : CmdBaseWidgetCommand(widget), m_color(col) { - Q_ASSERT(w != 0); - setText(i18n("Change fill color : %1", w->name())); - m_oldColor = w->fillColor(); + setText(i18n("Change fill color : %1", widget->name())); + + m_oldColor = widget->fillColor(); } CmdChangeFillColor::~CmdChangeFillColor() @@ -35,17 +34,11 @@ void CmdChangeFillColor::redo() { - UMLScene* scene = m_widget->umlScene(); - if (scene && scene->widgetOnDiagram(m_widget->id())) { - m_widget->setFillColorcmd(m_color); - } + widget()->setFillColorCmd(m_color); } void CmdChangeFillColor::undo() { - UMLScene* scene = m_widget->umlScene(); - if (scene && scene->widgetOnDiagram(m_widget->id())) { - m_widget->setFillColorcmd(m_oldColor); - } + widget()->setFillColorCmd(m_oldColor); } } diff -Nru umbrello-4.12.3/umbrello/cmds/widget/cmd_changeFillColor.h umbrello-4.12.90/umbrello/cmds/widget/cmd_changeFillColor.h --- umbrello-4.12.3/umbrello/cmds/widget/cmd_changeFillColor.h 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/cmds/widget/cmd_changeFillColor.h 2014-03-05 15:04:09.000000000 +0000 @@ -13,15 +13,15 @@ #ifndef CMD_CHANGEFILLCOLOR_H #define CMD_CHANGEFILLCOLOR_H +#include "cmd_baseWidgetCommand.h" + #include -#include class UMLWidget; namespace Uml { - - class CmdChangeFillColor : public QUndoCommand + class CmdChangeFillColor : public CmdBaseWidgetCommand { public: CmdChangeFillColor(UMLWidget* w, const QColor& col); @@ -31,9 +31,8 @@ void undo(); private: - UMLWidget* m_widget; - QColor m_oldColor; ///< old color - QColor m_color; ///< new color + QColor m_oldColor; ///< old color + QColor m_color; ///< new color }; } diff -Nru umbrello-4.12.3/umbrello/cmds/widget/cmd_changeFont.cpp umbrello-4.12.90/umbrello/cmds/widget/cmd_changeFont.cpp --- umbrello-4.12.3/umbrello/cmds/widget/cmd_changeFont.cpp 1970-01-01 00:00:00.000000000 +0000 +++ umbrello-4.12.90/umbrello/cmds/widget/cmd_changeFont.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -0,0 +1,40 @@ +/*************************************************************************** + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * copyright (C) 2007-2013 * + * Umbrello UML Modeller Authors * + ***************************************************************************/ + +#include "cmd_changeFont.h" + +// app includes +#include "umlwidget.h" + +// kde includes +#include + +namespace Uml +{ + CmdChangeFont::CmdChangeFont(UMLWidget* widget, QFont font) + : CmdBaseWidgetCommand(widget) + { + setText(i18n("Change font : %1", widget->name())); + + m_newFont = font; + m_oldFont = widget->font(); + } + + void CmdChangeFont::undo() + { + widget()->setFontCmd(m_oldFont); + } + + void CmdChangeFont::redo() + { + widget()->setFontCmd(m_newFont); + } + +} diff -Nru umbrello-4.12.3/umbrello/cmds/widget/cmd_changeFont.h umbrello-4.12.90/umbrello/cmds/widget/cmd_changeFont.h --- umbrello-4.12.3/umbrello/cmds/widget/cmd_changeFont.h 1970-01-01 00:00:00.000000000 +0000 +++ umbrello-4.12.90/umbrello/cmds/widget/cmd_changeFont.h 2014-03-05 15:04:09.000000000 +0000 @@ -0,0 +1,36 @@ +/*************************************************************************** + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * copyright (C) 2002-2013 * + * Umbrello UML Modeller Authors * + ***************************************************************************/ + +#ifndef CMD_CHANGEFONT_H +#define CMD_CHANGEFONT_H + +#include "cmd_baseWidgetCommand.h" + +#include + +class UMLWidget; + +namespace Uml +{ + class CmdChangeFont : public CmdBaseWidgetCommand + { + public: + CmdChangeFont(UMLWidget* widget, QFont font); + + void undo(); + void redo(); + + private: + QFont m_newFont; + QFont m_oldFont; + }; +} + +#endif // CMD_CHANGEFONT_H diff -Nru umbrello-4.12.3/umbrello/cmds/widget/cmd_changeFontSelection.cpp umbrello-4.12.90/umbrello/cmds/widget/cmd_changeFontSelection.cpp --- umbrello-4.12.3/umbrello/cmds/widget/cmd_changeFontSelection.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/cmds/widget/cmd_changeFontSelection.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,45 +0,0 @@ -/*************************************************************************** - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * copyright (C) 2007-2013 * - * Umbrello UML Modeller Authors * - ***************************************************************************/ - -#include "cmd_changeFontSelection.h" - -// app includes -#include "umldoc.h" -#include "umlscene.h" -#include "umlwidget.h" - -// kde includes -#include - -namespace Uml -{ - CmdChangeFontSelection::CmdChangeFontSelection(UMLDoc* doc, UMLScene* scene, QFont fon) - { - UMLWidget * widget = scene->getFirstMultiSelectedWidget(); - setText(i18n("Change font : %1", widget->name())); - m_doc = doc; - m_scene = scene; - m_newFont = fon; - m_oldFont = widget->font(); - } - - void CmdChangeFontSelection::undo() - { - m_scene->selectionSetFont(m_oldFont); - m_doc->setModified(true); - } - - void CmdChangeFontSelection::redo() - { - m_scene->selectionSetFont(m_newFont); - m_doc->setModified(true); - } - -} diff -Nru umbrello-4.12.3/umbrello/cmds/widget/cmd_changeFontSelection.h umbrello-4.12.90/umbrello/cmds/widget/cmd_changeFontSelection.h --- umbrello-4.12.3/umbrello/cmds/widget/cmd_changeFontSelection.h 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/cmds/widget/cmd_changeFontSelection.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,38 +0,0 @@ -/*************************************************************************** - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * copyright (C) 2002-2013 * - * Umbrello UML Modeller Authors * - ***************************************************************************/ - -#ifndef CMD_CHANGEFONTSELECTION_H -#define CMD_CHANGEFONTSELECTION_H - -#include -#include - -class UMLDoc; -class UMLScene; - -namespace Uml -{ - class CmdChangeFontSelection: public QUndoCommand - { - public: - CmdChangeFontSelection(UMLDoc* doc, UMLScene* scene, QFont fon); - - void undo(); - void redo(); - - private: - UMLDoc* m_doc; - UMLScene* m_scene; - QFont m_newFont; - QFont m_oldFont; - }; -} - -#endif // CMD_CHANGEFONTSELECTION_H diff -Nru umbrello-4.12.3/umbrello/cmds/widget/cmd_changeLineColor.cpp umbrello-4.12.90/umbrello/cmds/widget/cmd_changeLineColor.cpp --- umbrello-4.12.3/umbrello/cmds/widget/cmd_changeLineColor.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/cmds/widget/cmd_changeLineColor.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -11,7 +11,6 @@ #include "cmd_changeLineColor.h" // app includes -#include "umlscene.h" #include "umlwidget.h" // kde includes @@ -20,22 +19,14 @@ namespace Uml { - /*CmdChangeLineColor::CmdChangeLineColor(UMLView *view, const QColor& col) - { - setText(i18n("Change Line Color")); - UMLWidget * widget = view->getFirstMultiSelectedWidget(); - m_view = view; - m_newColor = col; - m_oldColor = widget->lineColor(); - }*/ - - CmdChangeLineColor::CmdChangeLineColor(UMLWidget *w, const QColor& col) - : m_widget(w), + CmdChangeLineColor::CmdChangeLineColor(UMLWidget* widget, const QColor& col) + : CmdBaseWidgetCommand(widget), m_newColor(col) { - Q_ASSERT(w != 0); - setText(i18n("Change line color : %1", w->name())); - m_oldColor= w->lineColor() ; + setText(i18n("Change line color : %1", widget->name())); + + m_oldColor = widget->lineColor() ; + m_oldUsesDiagramValue = widget->usesDiagramLineColor(); } CmdChangeLineColor::~CmdChangeLineColor() @@ -44,18 +35,14 @@ void CmdChangeLineColor::redo() { - UMLScene* scene = m_widget->umlScene(); - if (scene && scene->widgetOnDiagram(m_widget->id())) { - m_widget->setLineColorcmd(m_newColor); - } + widget()->setLineColorCmd(m_newColor); } void CmdChangeLineColor::undo() { - UMLScene* scene = m_widget->umlScene(); - if (scene && scene->widgetOnDiagram(m_widget->id())) { - m_widget->setLineColorcmd(m_oldColor); - } + UMLWidget* umlWidget = widget(); + umlWidget->setLineColorCmd(m_oldColor); + umlWidget->setUsesDiagramLineColor(m_oldUsesDiagramValue); } } diff -Nru umbrello-4.12.3/umbrello/cmds/widget/cmd_changeLineColor.h umbrello-4.12.90/umbrello/cmds/widget/cmd_changeLineColor.h --- umbrello-4.12.3/umbrello/cmds/widget/cmd_changeLineColor.h 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/cmds/widget/cmd_changeLineColor.h 2014-03-05 15:04:09.000000000 +0000 @@ -11,14 +11,15 @@ #ifndef CMD_CHANGELINECOLOR_H #define CMD_CHANGELINECOLOR_H +#include "cmd_baseWidgetCommand.h" + #include -#include class UMLWidget; namespace Uml { - class CmdChangeLineColor : public QUndoCommand + class CmdChangeLineColor : public CmdBaseWidgetCommand { public: CmdChangeLineColor(UMLWidget *w, const QColor& col); @@ -27,9 +28,9 @@ void undo(); private: - UMLWidget* m_widget; - QColor m_oldColor; - QColor m_newColor; + QColor m_oldColor; + QColor m_newColor; + bool m_oldUsesDiagramValue; }; } diff -Nru umbrello-4.12.3/umbrello/cmds/widget/cmd_changeLineWidth.cpp umbrello-4.12.90/umbrello/cmds/widget/cmd_changeLineWidth.cpp --- umbrello-4.12.3/umbrello/cmds/widget/cmd_changeLineWidth.cpp 1970-01-01 00:00:00.000000000 +0000 +++ umbrello-4.12.90/umbrello/cmds/widget/cmd_changeLineWidth.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -0,0 +1,45 @@ +/*************************************************************************** + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * copyright (C) 2002-2013 * + * Umbrello UML Modeller Authors * + ***************************************************************************/ + +#include "cmd_changeLineWidth.h" + +// app includes +#include "umlscene.h" +#include "umlwidget.h" + +// kde includes +#include + +namespace Uml +{ + + CmdChangeLineWidth::CmdChangeLineWidth(UMLWidget* widget, const uint width) + : CmdBaseWidgetCommand(widget), + m_newWidth(width) + { + setText(i18n("Change line width : %1", widget->name())); + + m_oldWidth = widget->lineWidth() ; + } + + CmdChangeLineWidth::~CmdChangeLineWidth() + { + } + + void CmdChangeLineWidth::redo() + { + widget()->setLineWidthCmd(m_newWidth); + } + + void CmdChangeLineWidth::undo() + { + widget()->setLineWidthCmd(m_oldWidth); + } +} diff -Nru umbrello-4.12.3/umbrello/cmds/widget/cmd_changeLineWidth.h umbrello-4.12.90/umbrello/cmds/widget/cmd_changeLineWidth.h --- umbrello-4.12.3/umbrello/cmds/widget/cmd_changeLineWidth.h 1970-01-01 00:00:00.000000000 +0000 +++ umbrello-4.12.90/umbrello/cmds/widget/cmd_changeLineWidth.h 2014-03-05 15:04:09.000000000 +0000 @@ -0,0 +1,34 @@ +/*************************************************************************** + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * copyright (C) 2002-2013 * + * Umbrello UML Modeller Authors * + ***************************************************************************/ + +#ifndef CMD_CHANGELINEWIDTH_H +#define CMD_CHANGELINEWIDTH_H + +#include "cmd_baseWidgetCommand.h" + +class UMLWidget; + +namespace Uml +{ + class CmdChangeLineWidth : public CmdBaseWidgetCommand + { + public: + CmdChangeLineWidth(UMLWidget *w, const uint width); + ~CmdChangeLineWidth(); + void redo(); + void undo(); + + private: + uint m_oldWidth; + uint m_newWidth; + }; +} + +#endif // CMD_CHANGELINEWIDTH_H diff -Nru umbrello-4.12.3/umbrello/cmds/widget/cmd_changeTextColor.cpp umbrello-4.12.90/umbrello/cmds/widget/cmd_changeTextColor.cpp --- umbrello-4.12.3/umbrello/cmds/widget/cmd_changeTextColor.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/cmds/widget/cmd_changeTextColor.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -19,13 +19,14 @@ namespace Uml { - CmdChangeTextColor::CmdChangeTextColor(UMLWidget *w, const QColor& col) - : m_widget(w), + CmdChangeTextColor::CmdChangeTextColor(UMLWidget* widget, const QColor& col) + : CmdBaseWidgetCommand(widget), m_newColor(col) { - Q_ASSERT(w != 0); - setText(i18n("Change text color : %1", w->name())); - m_oldColor= w->textColor() ; + setText(i18n("Change text color : %1", widget->name())); + + m_oldColor = widget->textColor() ; + m_oldUsesDiagramValue = widget->usesDiagramTextColor(); } CmdChangeTextColor::~CmdChangeTextColor() @@ -34,18 +35,14 @@ void CmdChangeTextColor::redo() { - UMLScene* scene = m_widget->umlScene(); - if (scene && scene->widgetOnDiagram(m_widget->id())) { - m_widget->setTextColorcmd(m_newColor); - } + widget()->setTextColorCmd(m_newColor); } void CmdChangeTextColor::undo() { - UMLScene* scene = m_widget->umlScene(); - if (scene && scene->widgetOnDiagram(m_widget->id())) { - m_widget->setTextColorcmd(m_oldColor); - } + UMLWidget* umlWidget = widget(); + umlWidget->setTextColorCmd(m_oldColor); + umlWidget->setUsesDiagramTextColor(m_oldUsesDiagramValue); } } diff -Nru umbrello-4.12.3/umbrello/cmds/widget/cmd_changeTextColor.h umbrello-4.12.90/umbrello/cmds/widget/cmd_changeTextColor.h --- umbrello-4.12.3/umbrello/cmds/widget/cmd_changeTextColor.h 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/cmds/widget/cmd_changeTextColor.h 2014-03-05 15:04:09.000000000 +0000 @@ -11,14 +11,15 @@ #ifndef CMD_CHANGETEXTCOLOR_H #define CMD_CHANGETEXTCOLOR_H +#include "cmd_baseWidgetCommand.h" + #include -#include class UMLWidget; namespace Uml { - class CmdChangeTextColor : public QUndoCommand + class CmdChangeTextColor : public CmdBaseWidgetCommand { public: CmdChangeTextColor(UMLWidget *w, const QColor& col); @@ -27,9 +28,9 @@ void undo(); private: - UMLWidget* m_widget; QColor m_oldColor; QColor m_newColor; + bool m_oldUsesDiagramValue; }; } diff -Nru umbrello-4.12.3/umbrello/cmds/widget/cmd_changeUseFillColor.cpp umbrello-4.12.90/umbrello/cmds/widget/cmd_changeUseFillColor.cpp --- umbrello-4.12.3/umbrello/cmds/widget/cmd_changeUseFillColor.cpp 1970-01-01 00:00:00.000000000 +0000 +++ umbrello-4.12.90/umbrello/cmds/widget/cmd_changeUseFillColor.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -0,0 +1,47 @@ +/*************************************************************************** + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * copyright (C) 2002-2013 * + * Umbrello UML Modeller Authors * + ***************************************************************************/ + +#include "cmd_changeUseFillColor.h" + +#include "umlscene.h" +#include "umlwidget.h" + +// kde includes +#include + +namespace Uml +{ + CmdChangeUseFillColor::CmdChangeUseFillColor(UMLWidget* widget, bool value) + : CmdBaseWidgetCommand(widget), + m_newValue(value) + { + if (value) { + setText(i18n("Use fill color : %1", widget->name())); + } else { + setText(i18n("No fill color : %1", widget->name())); + } + + m_oldValue = widget->useFillColor(); + } + + CmdChangeUseFillColor::~CmdChangeUseFillColor() + { + } + + void CmdChangeUseFillColor::redo() + { + widget()->setUseFillColorCmd(m_newValue); + } + + void CmdChangeUseFillColor::undo() + { + widget()->setUseFillColorCmd(m_oldValue); + } +} diff -Nru umbrello-4.12.3/umbrello/cmds/widget/cmd_changeUseFillColor.h umbrello-4.12.90/umbrello/cmds/widget/cmd_changeUseFillColor.h --- umbrello-4.12.3/umbrello/cmds/widget/cmd_changeUseFillColor.h 1970-01-01 00:00:00.000000000 +0000 +++ umbrello-4.12.90/umbrello/cmds/widget/cmd_changeUseFillColor.h 2014-03-05 15:04:09.000000000 +0000 @@ -0,0 +1,36 @@ +/*************************************************************************** + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * copyright (C) 2002-2013 * + * Umbrello UML Modeller Authors * + ***************************************************************************/ + +#ifndef CMD_CHANGEUSEFILLCOLOR_H +#define CMD_CHANGEUSEFILLCOLOR_H + +#include "cmd_baseWidgetCommand.h" + +class UMLWidget; + +namespace Uml +{ + + class CmdChangeUseFillColor : public CmdBaseWidgetCommand + { + public: + CmdChangeUseFillColor(UMLWidget* w, const bool value); + ~CmdChangeUseFillColor(); + + void redo(); + void undo(); + + private: + bool m_oldValue; + bool m_newValue; + }; +} + +#endif diff -Nru umbrello-4.12.3/umbrello/cmds/widget/cmd_changeVisualProperty.cpp umbrello-4.12.90/umbrello/cmds/widget/cmd_changeVisualProperty.cpp --- umbrello-4.12.3/umbrello/cmds/widget/cmd_changeVisualProperty.cpp 1970-01-01 00:00:00.000000000 +0000 +++ umbrello-4.12.90/umbrello/cmds/widget/cmd_changeVisualProperty.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -0,0 +1,58 @@ +/*************************************************************************** + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * copyright (C) 2002-2013 * + * Umbrello UML Modeller Authors * + ***************************************************************************/ + +#include "cmd_changeVisualProperty.h" + +// app includes +#include "classifierwidget.h" +#include "umlwidget.h" +#include "debug_utils.h" + +// kde includes +#include + +namespace Uml +{ + + CmdChangeVisualProperty::CmdChangeVisualProperty( + ClassifierWidget* widget, + ClassifierWidget::VisualProperty property, + bool value + ) : CmdBaseWidgetCommand(widget), + m_property(property), + m_newValue(value) + { + setText(i18n("Change visual property : %1", widget->name())); + + m_oldValue = widget->visualProperty(property); + } + + CmdChangeVisualProperty::~CmdChangeVisualProperty() + { + } + + void CmdChangeVisualProperty::redo() + { + ClassifierWidget* classifier = dynamic_cast(widget()); + if (classifier) + classifier->setVisualPropertyCmd(m_property, m_newValue); + else + uWarning() << "could not find classifier widget with id" << Uml::ID::toString(m_widgetId); + } + + void CmdChangeVisualProperty::undo() + { + ClassifierWidget* classifier = dynamic_cast(widget()); + if (classifier) + classifier->setVisualPropertyCmd(m_property, m_oldValue); + else + uWarning() << "could not find classifier widget with id" << Uml::ID::toString(m_widgetId); + } +} diff -Nru umbrello-4.12.3/umbrello/cmds/widget/cmd_changeVisualProperty.h umbrello-4.12.90/umbrello/cmds/widget/cmd_changeVisualProperty.h --- umbrello-4.12.3/umbrello/cmds/widget/cmd_changeVisualProperty.h 1970-01-01 00:00:00.000000000 +0000 +++ umbrello-4.12.90/umbrello/cmds/widget/cmd_changeVisualProperty.h 2014-03-05 15:04:09.000000000 +0000 @@ -0,0 +1,37 @@ +/*************************************************************************** + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * copyright (C) 2002-2013 * + * Umbrello UML Modeller Authors * + ***************************************************************************/ + +#ifndef CMD_CHANGEVISUALPROPERTY_H +#define CMD_CHANGEVISUALPROPERTY_H + +#include "classifierwidget.h" +#include "cmd_baseWidgetCommand.h" + +class UMLWidget; +class UMLScene; + +namespace Uml +{ + class CmdChangeVisualProperty : public CmdBaseWidgetCommand + { + public: + CmdChangeVisualProperty(ClassifierWidget* widget, ClassifierWidget::VisualProperty property, bool value); + ~CmdChangeVisualProperty(); + void redo(); + void undo(); + + private: + ClassifierWidget::VisualProperty m_property; + bool m_newValue; + bool m_oldValue; + }; +} + +#endif // CMD_CHANGEVISUALPROPERTY_H diff -Nru umbrello-4.12.3/umbrello/cmds/widget/cmd_createWidget.cpp umbrello-4.12.90/umbrello/cmds/widget/cmd_createWidget.cpp --- umbrello-4.12.3/umbrello/cmds/widget/cmd_createWidget.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/cmds/widget/cmd_createWidget.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -11,8 +11,8 @@ #include "cmd_createWidget.h" // app includes -#include "umlwidget.h" #include "umlscene.h" +#include "umlwidget.h" // kde includes #include @@ -20,37 +20,52 @@ namespace Uml { + /** + * Constructor. + */ CmdCreateWidget::CmdCreateWidget(UMLWidget* widget) - : m_widget(widget) + : CmdBaseWidgetCommand(widget) { - Q_ASSERT(widget != 0); setText(i18n("Create widget : %1", widget->name())); + + addWidgetToScene(widget); + + QDomDocument doc; + m_element = doc.createElement("widget"); + widget->saveToXMI(doc, m_element); } + /** + * Destructor. + */ CmdCreateWidget::~CmdCreateWidget() { } /** - * Create the UMLWidget. + * Create the widget */ void CmdCreateWidget::redo() { - UMLScene* scene = m_widget->umlScene(); - if (scene && scene->widgetOnDiagram(m_widget->id())) { - m_widget->setVisible(true); + UMLWidget* umlWidget = scene()->findWidgetByLocalId(m_widgetId); + if (umlWidget == 0) { + // If the widget is not found, the add command was undone. Load the + // widget back from the saved XMI state. + QDomElement widgetElement = m_element.firstChild().toElement(); + umlWidget = scene()->loadWidgetFromXMI(widgetElement); + + addWidgetToScene(umlWidget); } } /** - * Suppress the UMLWidget. + * Remove the widget */ void CmdCreateWidget::undo() { - UMLScene* scene = m_widget->umlScene(); - if (scene && scene->widgetOnDiagram(m_widget->id())) { - m_widget->setVisible(false); + UMLWidget* umlWidget = widget(); + if (umlWidget != 0) { + scene()->removeWidgetCmd(umlWidget); } } - } diff -Nru umbrello-4.12.3/umbrello/cmds/widget/cmd_createWidget.h umbrello-4.12.90/umbrello/cmds/widget/cmd_createWidget.h --- umbrello-4.12.3/umbrello/cmds/widget/cmd_createWidget.h 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/cmds/widget/cmd_createWidget.h 2014-03-05 15:04:09.000000000 +0000 @@ -11,23 +11,25 @@ #ifndef CMD_CREATE_WIDGET_H #define CMD_CREATE_WIDGET_H -#include +#include "cmd_baseWidgetCommand.h" + +#include class UMLWidget; namespace Uml { - class CmdCreateWidget : public QUndoCommand + class CmdCreateWidget : public CmdBaseWidgetCommand { - public: - CmdCreateWidget(UMLWidget* widget); - ~CmdCreateWidget(); + public: + explicit CmdCreateWidget(UMLWidget* widget); + ~CmdCreateWidget(); - void redo(); - void undo(); + void redo(); + void undo(); - private: - UMLWidget* m_widget; + private: + QDomElement m_element; }; } diff -Nru umbrello-4.12.3/umbrello/cmds/widget/cmd_moveWidget.cpp umbrello-4.12.90/umbrello/cmds/widget/cmd_moveWidget.cpp --- umbrello-4.12.3/umbrello/cmds/widget/cmd_moveWidget.cpp 1970-01-01 00:00:00.000000000 +0000 +++ umbrello-4.12.90/umbrello/cmds/widget/cmd_moveWidget.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -0,0 +1,59 @@ +/*************************************************************************** + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * copyright (C) 2002-2013 * + * Umbrello UML Modeller Authors * + ***************************************************************************/ + +#include "cmd_moveWidget.h" + +// app includes +#include "basictypes.h" +#include "umlscene.h" +#include "umlwidget.h" + +#include + +namespace Uml +{ + + CmdMoveWidget::CmdMoveWidget(UMLWidget *widget) + : CmdBaseWidgetCommand(widget) + { + setText(i18n("Move widget : %1", widget->name())); + + m_pos = widget->pos(); + m_posOld = widget->startMovePosition(); + } + + CmdMoveWidget::~CmdMoveWidget() + { + } + + void CmdMoveWidget::redo() + { + UMLWidget* umlWidget = widget(); + umlWidget->setPos(m_pos); + umlWidget->updateGeometry(); + } + + void CmdMoveWidget::undo() + { + UMLWidget* umlWidget = widget(); + umlWidget->setPos(m_posOld); + umlWidget->updateGeometry(); + } + +// bool CmdMoveWidget::mergeWith(const QUndoCommand* other) +// { +// const CmdMoveWidget* otherCmd = static_cast(other); +// if (m_widgetCtrl != otherCmd->m_widgetCtrl) +// return false; +// m_x = otherCmd->m_x; +// m_y = otherCmd->m_y; +// return true; +// } +} diff -Nru umbrello-4.12.3/umbrello/cmds/widget/cmd_moveWidget.h umbrello-4.12.90/umbrello/cmds/widget/cmd_moveWidget.h --- umbrello-4.12.3/umbrello/cmds/widget/cmd_moveWidget.h 1970-01-01 00:00:00.000000000 +0000 +++ umbrello-4.12.90/umbrello/cmds/widget/cmd_moveWidget.h 2014-03-05 15:04:09.000000000 +0000 @@ -0,0 +1,38 @@ +/*************************************************************************** + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * copyright (C) 2002-2013 * + * Umbrello UML Modeller Authors * + ***************************************************************************/ + +#ifndef CMD_MOVEWIDGET_H +#define CMD_MOVEWIDGET_H + +#include "cmd_baseWidgetCommand.h" + +#include + +class UMLWidget; + +namespace Uml +{ + class CmdMoveWidget : public CmdBaseWidgetCommand + { + public: + explicit CmdMoveWidget(UMLWidget* widget); + ~CmdMoveWidget(); + + void redo(); + void undo(); + + private: + QPointF m_pos; + QPointF m_posOld; + + }; +} + +#endif diff -Nru umbrello-4.12.3/umbrello/cmds/widget/cmd_removeWidget.cpp umbrello-4.12.90/umbrello/cmds/widget/cmd_removeWidget.cpp --- umbrello-4.12.3/umbrello/cmds/widget/cmd_removeWidget.cpp 1970-01-01 00:00:00.000000000 +0000 +++ umbrello-4.12.90/umbrello/cmds/widget/cmd_removeWidget.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -0,0 +1,67 @@ +/*************************************************************************** + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * copyright (C) 2002-2013 * + * Umbrello UML Modeller Authors * + ***************************************************************************/ + +#include "cmd_removeWidget.h" + +// app includes +#include "umlscene.h" +#include "umlwidget.h" + +// kde includes +#include + +namespace Uml +{ + + /** + * Constructor. + */ + CmdRemoveWidget::CmdRemoveWidget(UMLWidget* widget) + : CmdBaseWidgetCommand(widget) + { + setText(i18n("Remove widget : %1", widget->name())); + + QDomDocument doc; + m_element = doc.createElement("widget"); + widget->saveToXMI(doc, m_element); + } + + /** + * Destructor. + */ + CmdRemoveWidget::~CmdRemoveWidget() + { + } + + /** + * Remove the widget + */ + void CmdRemoveWidget::redo() + { + UMLScene* umlScene = scene(); + UMLWidget* widget = umlScene->findWidgetByLocalId(m_widgetId); + if (widget != 0) { + umlScene->removeWidgetCmd(widget); + } + } + + /** + * Add the widget back + */ + void CmdRemoveWidget::undo() + { + QDomElement widgetElement = m_element.firstChild().toElement(); + + UMLScene* umlScene = scene(); + UMLWidget* widget = umlScene->loadWidgetFromXMI(widgetElement); + + addWidgetToScene(widget); + } +} diff -Nru umbrello-4.12.3/umbrello/cmds/widget/cmd_removeWidget.h umbrello-4.12.90/umbrello/cmds/widget/cmd_removeWidget.h --- umbrello-4.12.3/umbrello/cmds/widget/cmd_removeWidget.h 1970-01-01 00:00:00.000000000 +0000 +++ umbrello-4.12.90/umbrello/cmds/widget/cmd_removeWidget.h 2014-03-05 15:04:09.000000000 +0000 @@ -0,0 +1,37 @@ +/*************************************************************************** + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * copyright (C) 2002-2013 * + * Umbrello UML Modeller Authors * + ***************************************************************************/ + +#ifndef CMD_REMOVE_WIDGET_H +#define CMD_REMOVE_WIDGET_H + +#include "cmd_baseWidgetCommand.h" + +#include + +class UMLScene; +class UMLWidget; + +namespace Uml +{ + class CmdRemoveWidget : public CmdBaseWidgetCommand + { + public: + explicit CmdRemoveWidget(UMLWidget* widget); + ~CmdRemoveWidget(); + + void redo(); + void undo(); + + private: + QDomElement m_element; + }; +} + +#endif diff -Nru umbrello-4.12.3/umbrello/cmds/widget/cmd_resizeWidget.cpp umbrello-4.12.90/umbrello/cmds/widget/cmd_resizeWidget.cpp --- umbrello-4.12.3/umbrello/cmds/widget/cmd_resizeWidget.cpp 1970-01-01 00:00:00.000000000 +0000 +++ umbrello-4.12.90/umbrello/cmds/widget/cmd_resizeWidget.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -0,0 +1,46 @@ +/*************************************************************************** + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * copyright (C) 2002-2013 * + * Umbrello UML Modeller Authors * + ***************************************************************************/ + +#include "cmd_resizeWidget.h" + +// app includes +#include "umlscene.h" +#include "umlwidget.h" + +#include + +namespace Uml +{ + + CmdResizeWidget::CmdResizeWidget(UMLWidget *widget) + : CmdBaseWidgetCommand(widget) + { + Q_ASSERT(widget != 0); + setText(i18n("Resize widget : %1", widget->name())); + + m_size = QSizeF(widget->width(), widget->height()); + m_sizeOld = widget->startResizeSize(); + } + + CmdResizeWidget::~CmdResizeWidget() + { + } + + void CmdResizeWidget::redo() + { + widget()->setSize(m_size); + } + + void CmdResizeWidget::undo() + { + widget()->setSize(m_sizeOld); + } + +} diff -Nru umbrello-4.12.3/umbrello/cmds/widget/cmd_resizeWidget.h umbrello-4.12.90/umbrello/cmds/widget/cmd_resizeWidget.h --- umbrello-4.12.3/umbrello/cmds/widget/cmd_resizeWidget.h 1970-01-01 00:00:00.000000000 +0000 +++ umbrello-4.12.90/umbrello/cmds/widget/cmd_resizeWidget.h 2014-03-05 15:04:09.000000000 +0000 @@ -0,0 +1,37 @@ +/*************************************************************************** + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * copyright (C) 2002-2013 * + * Umbrello UML Modeller Authors * + ***************************************************************************/ + +#ifndef CMD_RESIZEWIDGET_H +#define CMD_RESIZEWIDGET_H + +#include "cmd_baseWidgetCommand.h" + +#include + +class UMLWidget; + +namespace Uml +{ + class CmdResizeWidget : public CmdBaseWidgetCommand + { + public: + explicit CmdResizeWidget(UMLWidget* widget); + ~CmdResizeWidget(); + + void redo(); + void undo(); + + private: + QSizeF m_size; + QSizeF m_sizeOld; + }; +} + +#endif diff -Nru umbrello-4.12.3/umbrello/cmds/widget/cmd_setName.cpp umbrello-4.12.90/umbrello/cmds/widget/cmd_setName.cpp --- umbrello-4.12.3/umbrello/cmds/widget/cmd_setName.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/cmds/widget/cmd_setName.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -20,7 +20,8 @@ { CmdSetName::CmdSetName(UMLObject * obj, const QString& name) - : m_umlObject(obj), m_name(name) + : CmdBaseObjectCommand(obj), + m_name(name) { setText(i18n("Set name : %1 to %2", obj->name(), name)); m_oldname = obj->name(); @@ -32,12 +33,16 @@ void CmdSetName::redo() { - m_umlObject->setNameCmd(m_name); + UMLObject *umlObject = object(); + if (umlObject) + umlObject->setNameCmd(m_name); } void CmdSetName::undo() { - m_umlObject->setNameCmd(m_oldname); + UMLObject *umlObject = object(); + if (umlObject) + umlObject->setNameCmd(m_oldname); } } diff -Nru umbrello-4.12.3/umbrello/cmds/widget/cmd_setName.h umbrello-4.12.90/umbrello/cmds/widget/cmd_setName.h --- umbrello-4.12.3/umbrello/cmds/widget/cmd_setName.h 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/cmds/widget/cmd_setName.h 2014-03-05 15:04:09.000000000 +0000 @@ -11,13 +11,11 @@ #ifndef CMD_SETNAME_H #define CMD_SETNAME_H -#include - -class UMLObject; +#include "cmd_baseObjectCommand.h" namespace Uml { - class CmdSetName : public QUndoCommand + class CmdSetName : public CmdBaseObjectCommand { public: CmdSetName(UMLObject* obj, const QString& name); @@ -28,7 +26,6 @@ private: QString m_oldname; - UMLObject* m_umlObject; QString m_name; }; } diff -Nru umbrello-4.12.3/umbrello/cmds.h umbrello-4.12.90/umbrello/cmds.h --- umbrello-4.12.3/umbrello/cmds.h 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/cmds.h 2014-03-05 15:04:09.000000000 +0000 @@ -18,8 +18,7 @@ #include "cmds/cmd_createDiagram.h" #include "cmds/cmd_handleRename.h" -#include "cmds/cmd_moveWidget.h" -#include "cmds/cmd_resizeWidget.h" +#include "cmds/cmd_removeDiagram.h" #include "cmds/cmd_setStereotype.h" #include "cmds/cmd_setVisibility.h" @@ -27,17 +26,24 @@ * Generic ************************************************************/ #include "cmds/generic/cmd_createUMLObject.h" +#include "cmds/generic/cmd_removeUMLObject.h" #include "cmds/generic/cmd_renameUMLObject.h" /************************************************************ * Widgets ************************************************************/ #include "cmds/widget/cmd_changeFillColor.h" -#include "cmds/widget/cmd_changeFontSelection.h" +#include "cmds/widget/cmd_changeFont.h" #include "cmds/widget/cmd_changeLineColor.h" +#include "cmds/widget/cmd_changeLineWidth.h" #include "cmds/widget/cmd_changeMultiplicity.h" #include "cmds/widget/cmd_changeTextColor.h" +#include "cmds/widget/cmd_changeUseFillColor.h" +#include "cmds/widget/cmd_changeVisualProperty.h" #include "cmds/widget/cmd_createWidget.h" +#include "cmds/widget/cmd_moveWidget.h" +#include "cmds/widget/cmd_removeWidget.h" +#include "cmds/widget/cmd_resizeWidget.h" #include "cmds/widget/cmd_setName.h" #include "cmds/widget/cmd_setTxt.h" diff -Nru umbrello-4.12.3/umbrello/codegenerators/codeclassfield.cpp umbrello-4.12.90/umbrello/codegenerators/codeclassfield.cpp --- umbrello-4.12.3/umbrello/codegenerators/codeclassfield.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/codegenerators/codeclassfield.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -291,7 +291,7 @@ if(method) method->loadFromXMI(element); else - uError()<<"Can not load code accessor method for type:"<getDocToolTag() + "param " + atName + ' ' + at->doc() + m_endl; } doc = doc.remove(doc.size() - 1, 1); // remove last endl of comment - str += ")"; + str += ')'; if (op->getConst()) str += " const"; diff -Nru umbrello-4.12.3/umbrello/codegenerators/java/javawriter.cpp umbrello-4.12.90/umbrello/codegenerators/java/javawriter.cpp --- umbrello-4.12.3/umbrello/codegenerators/java/javawriter.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/codegenerators/java/javawriter.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -922,7 +922,7 @@ str += ((op->isAbstract() && !m_isInterface) ? "abstract ":""); str += Uml::Visibility::toString(op->visibility()) + ' '; str += (op->isStatic() ? "static ":""); - str += methodReturnType + ' ' + cleanName(op->name()) + "("; + str += methodReturnType + ' ' + cleanName(op->name()) + '('; atl = op->getParmList(); i= atl.count(); @@ -939,7 +939,7 @@ j++; } doc = doc.remove(doc.size() - 1, 1); // remove last endl of comment - str+= ")"; + str+= ')'; // method only gets a body IF it is not abstract if (op->isAbstract() || m_isInterface) diff -Nru umbrello-4.12.3/umbrello/codegenerators/ownedcodeblock.cpp umbrello-4.12.90/umbrello/codegenerators/ownedcodeblock.cpp --- umbrello-4.12.3/umbrello/codegenerators/ownedcodeblock.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/codegenerators/ownedcodeblock.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -147,7 +147,7 @@ initFields (obj); // just the regular approach } else - uError() << "ERROR: can not load ownedcodeblock: parentUMLObject w/id:" + uError() << "ERROR: cannot load ownedcodeblock: parentUMLObject w/id:" << Uml::ID::toString(id) << " not found, corrupt save file?"; } diff -Nru umbrello-4.12.3/umbrello/codegenerators/ruby/rubycodeaccessormethod.cpp umbrello-4.12.90/umbrello/codegenerators/ruby/rubycodeaccessormethod.cpp --- umbrello-4.12.3/umbrello/codegenerators/ruby/rubycodeaccessormethod.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/codegenerators/ruby/rubycodeaccessormethod.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -210,7 +210,7 @@ break; default: // do nothing..no idea what this is - uWarning() << "Warning: can not generate RubyCodeAccessorMethod for type: " << getType(); + uWarning() << "Warning: cannot generate RubyCodeAccessorMethod for type: " << getType(); break; } diff -Nru umbrello-4.12.3/umbrello/codeimport/classimport.cpp umbrello-4.12.90/umbrello/codeimport/classimport.cpp --- umbrello-4.12.3/umbrello/codeimport/classimport.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/codeimport/classimport.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -65,6 +65,7 @@ UMLDoc *umldoc = UMLApp::app()->document(); uint processedFilesCount = 0; bool result = true; + umldoc->setLoading(true); foreach (const QString& fileName, fileNames) { umldoc->writeToStatusBar(i18n("Importing file: %1 Progress: %2/%3", fileName, processedFilesCount, fileNames.size())); @@ -72,6 +73,7 @@ result = false; processedFilesCount++; } + umldoc->setLoading(false); umldoc->writeToStatusBar(result ? i18nc("ready to status bar", "Ready.") : i18nc("failed to status bar", "Failed.")); return result; } diff -Nru umbrello-4.12.3/umbrello/codeimport/cppimport.cpp umbrello-4.12.90/umbrello/codeimport/cppimport.cpp --- umbrello-4.12.3/umbrello/codeimport/cppimport.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/codeimport/cppimport.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -11,14 +11,14 @@ // own header #include "cppimport.h" -// must be located here for win32 msvc (see kdevcppparser/position.h) -#include "kdevcppparser/lexer.h" -#include "kdevcppparser/driver.h" +#include "lexer.h" +#include "driver.h" #include "kdevcppparser/cpptree2uml.h" // app includes #include "debug_utils.h" #include "import_utils.h" +#include "uml.h" #include "umlobject.h" #include "package.h" #include "enum.h" @@ -30,6 +30,7 @@ #include "optionstate.h" // qt includes +#include #include // static members @@ -91,13 +92,13 @@ feedTheModel(includeFile); } } - TranslationUnitAST *ast = ms_driver->translationUnit(fileName); - if (ast == NULL) { + ParsedFilePointer ast = ms_driver->translationUnit(fileName); + if (ast.isNull()) { uError() << fileName << " not found"; return; } CppTree2Uml modelFeeder(fileName, m_thread); - modelFeeder.parseTranslationUnit(ast); + modelFeeder.parseTranslationUnit(*ast); } /** @@ -132,7 +133,24 @@ { if (ms_seenFiles.indexOf(fileName) != -1) return true; - if (!ms_driver->parseFile(fileName)) + bool result = ms_driver->parseFile(fileName); + foreach(const Problem &problem, ms_driver->problems(fileName)) { + QString level; + if (problem.level() == Problem::Level_Error) + level = "error"; + else if (problem.level() == Problem::Level_Warning) + level = "warning"; + else if (problem.level() == Problem::Level_Todo) + level = "todo"; + else if (problem.level() == Problem::Level_Fixme) + level = "fixme"; + + QString item = QString("%1:%2:%3: %4: %5") + .arg(fileName).arg(problem.line()+1) + .arg(problem.column()).arg(level).arg(problem.text()); + UMLApp::app()->logWindow()->addItem(item); + } + if (!result) return false; feedTheModel(fileName); return true; diff -Nru umbrello-4.12.3/umbrello/codeimport/import_utils.cpp umbrello-4.12.90/umbrello/codeimport/import_utils.cpp --- umbrello-4.12.3/umbrello/codeimport/import_utils.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/codeimport/import_utils.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -194,11 +194,14 @@ // DEBUG(DBG_SRC) << "Import_Utils::createUMLObject(" << name // << "): parentPkg is NULL, assuming Logical View"; parentPkg = logicalView; - } - if (parentPkg->baseType() == UMLObject::ot_Artifact) { + } else if (parentPkg->baseType() == UMLObject::ot_Artifact) { DEBUG(DBG_SRC) << "Import_Utils::createUMLObject(" << name << "): Artifact as parent package is not supported yet, using Logical View"; parentPkg = logicalView; + } else if (parentPkg->baseType() == UMLObject::ot_Association) { + DEBUG(DBG_SRC) << "Import_Utils::createUMLObject(" << name + << "): Association as parent package is not supported yet, using Logical View"; + parentPkg = logicalView; } UMLObject * o = umldoc->findUMLObject(name, type, parentPkg); bNewUMLObjectWasCreated = false; diff -Nru umbrello-4.12.3/umbrello/codeimport/kdevcppparser/assignFunctor.hpp umbrello-4.12.90/umbrello/codeimport/kdevcppparser/assignFunctor.hpp --- umbrello-4.12.3/umbrello/codeimport/kdevcppparser/assignFunctor.hpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/codeimport/kdevcppparser/assignFunctor.hpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,71 +0,0 @@ -/* - Copyright 2008 Jean Vittor - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of - the License or (at your option) version 3 or any later version - accepted by the membership of KDE e.V. (or its successor approved - by the membership of KDE e.V.), which shall act as a proxy - defined in Section 14 of version 3 of the license. - - 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, see . -*/ - -#ifndef ASSIGNFUNCTOR_H -#define ASSIGNFUNCTOR_H - -/** (Dirty) tool used in a rule to assign the result of a function - into a variable. Should be replaced by something of boost if it - exists. */ - -template -struct assignFunctorResultEval { - template - static void eval( DestinationT& p_destination, FunctorT const& p_functor, - CharT p); -}; - -template <> -template -void assignFunctorResultEval<0>::eval( DestinationT& p_destination, - FunctorT const& p_functor, CharT) { - p_destination = p_functor(); -} - -template <> -template -void assignFunctorResultEval<1>::eval( DestinationT& p_destination, - FunctorT const& p_functor, CharT p) { - p_destination = p_functor( p); -} - -template -struct assignFunctorResult_impl { - assignFunctorResult_impl( DestinationT& p_destination, - FunctorT const& p_functor) - : m_destination( p_destination), m_functor( p_functor) {} - - template - void operator()( CharT p) const { - assignFunctorResultEval::eval( m_destination, m_functor, p); - } - - DestinationT& m_destination; - FunctorT const& m_functor; -}; - -template -assignFunctorResult_impl -assignFunctorResult( DestinationT& p_destination, - FunctorT const& p_functor) -{return assignFunctorResult_impl( p_destination, - p_functor);} - -#endif diff -Nru umbrello-4.12.3/umbrello/codeimport/kdevcppparser/ast.cpp umbrello-4.12.90/umbrello/codeimport/kdevcppparser/ast.cpp --- umbrello-4.12.3/umbrello/codeimport/kdevcppparser/ast.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/codeimport/kdevcppparser/ast.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,1170 +0,0 @@ -/* This file is part of KDevelop - Copyright (C) 2002, 2003 Roberto Raggi - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "ast.h" - -#include "debug_utils.h" - -#include - -QString nodeTypeToString(int type) -{ - switch(type) - { - case NodeType_Generic: - return "Generic"; - case NodeType_TemplateArgumentList: - return "TemplateArgumentList"; - case NodeType_ClassOrNamespaceName: - return "ClassOrNamespaceName"; - case NodeType_Name: - return "Name"; - case NodeType_Declaration: - return "Declaration"; - case NodeType_TypeSpecifier: - return "TypeSpecifier"; - case NodeType_BaseSpecifier: - return "BaseSpecifier"; - case NodeType_BaseClause: - return "BaseClause"; - case NodeType_ClassSpecifier: - return "ClassSpecifier"; - case NodeType_Enumerator: - return "Enumerator"; - case NodeType_EnumSpecifier: - return "EnumSpecifier"; - case NodeType_ElaboratedTypeSpecifier: - return "ElaboratedTypeSpecifier"; - case NodeType_LinkageBody: - return "LinkageBody"; - case NodeType_LinkageSpecification: - return "LinkageSpecification"; - case NodeType_Namespace: - return "Namespace"; - case NodeType_NamespaceAlias: - return "NamespaceAlias"; - case NodeType_Using: - return "Using"; - case NodeType_UsingDirective: - return "UsingDirective"; - case NodeType_InitDeclaratorList: - return "InitDeclaratorList"; - case NodeType_Typedef: - return "Typedef"; - case NodeType_Declarator: - return "Declarator"; - case NodeType_InitDeclarator: - return "InitDeclarator"; - case NodeType_TemplateDeclaration: - return "TemplateDeclaration"; - case NodeType_SimpleDeclaration: - return "SimpleDeclaration"; - case NodeType_Statement: - return "Statement"; - case NodeType_IfStatement: - return "IfStatement"; - case NodeType_WhileStatement: - return "WhileStatement"; - case NodeType_DoStatement: - return "DoStatement"; - case NodeType_ForStatement: - return "ForStatement"; - case NodeType_SwitchStatement: - return "SwitchStatement"; - case NodeType_DeclarationStatement: - return "DeclarationStatement"; - case NodeType_StatementList: - return "StatementList"; - case NodeType_TranslationUnit: - return "TranslationUnit"; - case NodeType_FunctionDefinition: - return "FunctionDefinition"; - case NodeType_ExpressionStatement: - return "ExpressionStatement"; - case NodeType_ParameterDeclaration: - return "ParameterDeclaration"; - case NodeType_ParameterDeclarationList: - return "ParameterDeclarationList"; - case NodeType_ParameterDeclarationClause: - return "ParameterDeclarationClause"; - case NodeType_Group: - return "Group"; - case NodeType_AccessDeclaration: - return "AccessDeclaration"; - case NodeType_TypeParameter: - return "TypeParameter"; - case NodeType_TemplateParameter: - return "TemplateParameter"; - case NodeType_TemplateParameterList: - return "TemplateParameterList"; - case NodeType_Condition: - return "Condition"; - case NodeType_Custom: - return "Custom"; - } - - return QString(); -} - -// ------------------------------------------------------------------------ - -AST::AST() - : m_nodeType(NodeType_Generic), m_parent(0), - m_startPosition(), m_endPosition() -{ -} - -AST::~AST() -{ -#ifndef CPPPARSER_NO_CHILDREN - if(m_parent) - m_parent->removeChild(this); -#endif -} - -void AST::setStartPosition(Position const& p) {m_startPosition = p;} - -Position const& AST::getStartPosition() const {return m_startPosition;} - -void AST::setEndPosition(Position const& p) {m_endPosition = p;} - -Position const& AST::getEndPosition() const {return m_endPosition;} - -void AST::setParent(AST* parent) -{ -#ifndef CPPPARSER_NO_CHILDREN - if(m_parent) - m_parent->removeChild(this); -#endif - - m_parent = parent; - -#ifndef CPPPARSER_NO_CHILDREN - if(m_parent) - m_parent->appendChild(this); -#endif -} - -#ifndef CPPPARSER_NO_CHILDREN -void AST::appendChild(AST* child) -{ - m_children.append(child); -} - -void AST::removeChild(AST* child) -{ - m_children.removeOne(child); -} -#endif - -// ------------------------------------------------------------------------ - -NameAST::NameAST() - : m_global(false) -{ -} - -void NameAST::setGlobal(bool b) -{ - m_global = b; -} - -void NameAST::setUnqualifiedName(ClassOrNamespaceNameAST::Node& unqualifiedName) -{ - m_unqualifiedName = unqualifiedName; - if(m_unqualifiedName.get()) m_unqualifiedName->setParent(this); -} - -void NameAST::addClassOrNamespaceName(ClassOrNamespaceNameAST::Node& classOrNamespaceName) -{ - if(!classOrNamespaceName.get()) - return; - - classOrNamespaceName->setParent(this); - m_classOrNamespaceNameList.append(classOrNamespaceName.release()); -} - -QString NameAST::text() const -{ - if(!m_unqualifiedName.get()) - return QString(); - - QString str; - - if(m_global) - str += "::"; - - for(int i = 0; i < m_classOrNamespaceNameList.size(); ++i) { - str += m_classOrNamespaceNameList.at(i)->text() + "::"; - } - - if(m_unqualifiedName.get()) - str += m_unqualifiedName->text(); - - return str; -} - -// ------------------------------------------------------------------------ - -DeclarationAST::DeclarationAST() -{ -} - -// ------------------------------------------------------------------------ - -FileAST::FileAST() -{ -} - -// ------------------------------------------------------------------------ - -LinkageBodyAST::LinkageBodyAST() -{ -} - -void LinkageBodyAST::addDeclaration(DeclarationAST::Node& ast) -{ - if(!ast.get()) - return; - - ast->setParent(this); - m_declarationList.append(ast.release()); -} - -// ------------------------------------------------------------------------ - -LinkageSpecificationAST::LinkageSpecificationAST() -{ -} - -void LinkageSpecificationAST::setExternType(AST::Node& externType) -{ - m_externType = externType; - if(m_externType.get()) m_externType->setParent(this); -} - -void LinkageSpecificationAST::setLinkageBody(LinkageBodyAST::Node& linkageBody) -{ - m_linkageBody = linkageBody; - if(m_linkageBody.get()) m_linkageBody->setParent(this); -} - -void LinkageSpecificationAST::setDeclaration(DeclarationAST::Node& decl) -{ - m_declaration = decl; - if(m_declaration.get()) m_declaration->setParent(this); -} - -// ------------------------------------------------------------------------ - -TranslationUnitAST::TranslationUnitAST() -{ -} - -void TranslationUnitAST::addDeclaration(DeclarationAST::Node& ast) -{ - if(!ast.get()) - return; - - ast->setParent(this); - m_declarationList.append(ast.release()); -} - -// ------------------------------------------------------------------------ - -NamespaceAST::NamespaceAST() -{ -} - -void NamespaceAST::setNamespaceName(AST::Node& namespaceName) -{ - m_namespaceName = namespaceName; - if(m_namespaceName.get()) m_namespaceName->setParent(this); -} - -void NamespaceAST::setLinkageBody(LinkageBodyAST::Node& linkageBody) -{ - m_linkageBody = linkageBody; - if(m_linkageBody.get()) m_linkageBody->setParent(this); -} - -// ------------------------------------------------------------------------ - -NamespaceAliasAST::NamespaceAliasAST() -{ -} - -void NamespaceAliasAST::setNamespaceName(AST::Node& namespaceName) -{ - m_namespaceName = namespaceName; - if(m_namespaceName.get()) m_namespaceName->setParent(this); -} - -void NamespaceAliasAST::setAliasName(NameAST::Node& name) -{ - m_aliasName = name; - if(m_aliasName.get()) m_aliasName->setParent(this); -} - -// ------------------------------------------------------------------------ - -UsingAST::UsingAST() -{ -} - -void UsingAST::setTypeName(AST::Node& typeName) -{ - m_typeName = typeName; - if(m_typeName.get()) m_typeName->setParent(this); -} - -void UsingAST::setName(NameAST::Node& name) -{ - m_name = name; - if(m_name.get()) m_name->setParent(this); -} - -// ------------------------------------------------------------------------ - -UsingDirectiveAST::UsingDirectiveAST() -{ -} - -void UsingDirectiveAST::setName(NameAST::Node& name) -{ - m_name = name; - if(m_name.get()) m_name->setParent(this); -} - -TypedefAST::TypedefAST() -{ -} - -void TypeSpecifierAST::setName(NameAST::Node& name) -{ - m_name = name; - if(m_name.get()) m_name->setParent(this); -} - -void TypedefAST::setTypeSpec(TypeSpecifierAST::Node& typeSpec) -{ - m_typeSpec = typeSpec; - if(m_typeSpec.get()) m_typeSpec->setParent(this); -} - -void TypedefAST::setInitDeclaratorList(InitDeclaratorListAST::Node& initDeclaratorList) -{ - m_initDeclaratorList = initDeclaratorList; - if(m_initDeclaratorList.get()) m_initDeclaratorList->setParent(this); -} - -// ------------------------------------------------------------------------ - -TemplateArgumentListAST::TemplateArgumentListAST() -{ -} - -void TemplateArgumentListAST::addArgument(AST::Node& arg) -{ - if(!arg.get()) - return; - - arg->setParent(this); - m_argumentList.append(arg.release()); -} - -QString TemplateArgumentListAST::text() const -{ - QStringList l; - - for(int i = 0; i < m_argumentList.size(); ++i) { - l.append(m_argumentList.at(i)->text()); - } - - return l.join(", "); -} - -// ------------------------------------------------------------------------ - -TemplateDeclarationAST::TemplateDeclarationAST() -{ -} - -void TemplateDeclarationAST::setExported(AST::Node& exported) -{ - m_exported = exported; - if(m_exported.get()) m_exported->setParent(this); -} - -void TemplateDeclarationAST::setTemplateParameterList(TemplateParameterListAST::Node& templateParameterList) -{ - m_templateParameterList = templateParameterList; - if(m_templateParameterList.get()) m_templateParameterList->setParent(this); -} - -void TemplateDeclarationAST::setDeclaration(DeclarationAST::Node& declaration) -{ - m_declaration = declaration; - if(m_declaration.get()) m_declaration->setParent(this); -} - -// ------------------------------------------------------------------------ - -ClassOrNamespaceNameAST::ClassOrNamespaceNameAST() -{ -} - -void ClassOrNamespaceNameAST::setName(AST::Node& name) -{ - m_name = name; - if(m_name.get()) m_name->setParent(this); -} - -void ClassOrNamespaceNameAST::setTemplateArgumentList(TemplateArgumentListAST::Node& templateArgumentList) -{ - m_templateArgumentList = templateArgumentList; - if(m_templateArgumentList.get()) m_templateArgumentList->setParent(this); -} - -QString ClassOrNamespaceNameAST::text() const -{ - if(!m_name.get()) - return QString(); - - QString str = m_name->text(); - if(m_templateArgumentList.get()) - str += QString::fromLatin1("< ") + m_templateArgumentList->text() + QString::fromLatin1(" >"); - - return str; -} - -// ------------------------------------------------------------------------ - -TypeSpecifierAST::TypeSpecifierAST() -{ -} - -void TypeSpecifierAST::setCvQualify(GroupAST::Node& cvQualify) -{ - m_cvQualify = cvQualify; - if(m_cvQualify.get()) m_cvQualify->setParent(this); -} - -void TypeSpecifierAST::setCv2Qualify(GroupAST::Node& cv2Qualify) -{ - m_cv2Qualify = cv2Qualify; - if(m_cv2Qualify.get()) m_cv2Qualify->setParent(this); -} - -QString TypeSpecifierAST::text() const -{ - QString str; - - if(m_cvQualify.get()) - str += m_cvQualify->text() + ' '; - - if(m_name.get()) - str += m_name->text(); - - if(m_cv2Qualify.get()) - str += QString(" ") + m_cv2Qualify->text(); - - return str; -} - -// ------------------------------------------------------------------------ - -ClassSpecifierAST::ClassSpecifierAST() -{ -} - -void ClassSpecifierAST::setClassKey(AST::Node& classKey) -{ - m_classKey = classKey; - if(m_classKey.get()) m_classKey->setParent(this); -} - -void ClassSpecifierAST::addDeclaration(DeclarationAST::Node& declaration) -{ - if(!declaration.get()) - return; - - declaration->setParent(this); - m_declarationList.append(declaration.release()); -} - -void ClassSpecifierAST::setBaseClause(BaseClauseAST::Node& baseClause) -{ - m_baseClause = baseClause; - if(m_baseClause.get()) m_baseClause->setParent(this); -} - -// ------------------------------------------------------------------------ - -EnumSpecifierAST::EnumSpecifierAST() -{ -} - -void EnumSpecifierAST::addEnumerator(EnumeratorAST::Node& enumerator) -{ - if(!enumerator.get()) - return; - - enumerator->setParent(this); - m_enumeratorList.append(enumerator.release()); -} - - -// ------------------------------------------------------------------------ - -ElaboratedTypeSpecifierAST::ElaboratedTypeSpecifierAST() -{ -} - -void ElaboratedTypeSpecifierAST::setKind(AST::Node& kind) -{ - m_kind = kind; - if(m_kind.get()) m_kind->setParent(this); -} - -QString ElaboratedTypeSpecifierAST::text() const -{ - if(m_kind.get()) - return m_kind->text() + ' ' + TypeSpecifierAST::text(); - - return TypeSpecifierAST::text(); -} - -// ------------------------------------------------------------------------ - -StatementAST::StatementAST() -{ -} - -// ------------------------------------------------------------------------ - -EnumeratorAST::EnumeratorAST() -{ -} - -void EnumeratorAST::setId(AST::Node& id) -{ - m_id = id; - if(m_id.get()) m_id->setParent(this); -} - -void EnumeratorAST::setExpr(AST::Node& expr) -{ - m_expr = expr; - if(m_expr.get()) m_expr->setParent(this); -} - -// ------------------------------------------------------------------------ - -BaseClauseAST::BaseClauseAST() -{ -} - -void BaseClauseAST::addBaseSpecifier(BaseSpecifierAST::Node& baseSpecifier) -{ - if(!baseSpecifier.get()) - return; - - baseSpecifier->setParent(this); - m_baseSpecifierList.append(baseSpecifier.release()); -} - -// ------------------------------------------------------------------------ - -BaseSpecifierAST::BaseSpecifierAST() -{ -} - -void BaseSpecifierAST::setIsVirtual(AST::Node& isVirtual) -{ - m_isVirtual = isVirtual; - if(m_isVirtual.get()) m_isVirtual->setParent(this); -} - -void BaseSpecifierAST::setAccess(AST::Node& access) -{ - m_access = access; - if(m_access.get()) m_access->setParent(this); -} - -void BaseSpecifierAST::setName(NameAST::Node& name) -{ - m_name = name; - if(m_name.get()) m_name->setParent(this); -} - -// ------------------------------------------------------------------------ - -SimpleDeclarationAST::SimpleDeclarationAST() -{ -} - -void SimpleDeclarationAST::setFunctionSpecifier(GroupAST::Node& functionSpecifier) -{ - m_functionSpecifier = functionSpecifier; - if(m_functionSpecifier.get()) m_functionSpecifier->setParent(this); -} - -void SimpleDeclarationAST::setStorageSpecifier(GroupAST::Node& storageSpecifier) -{ - m_storageSpecifier = storageSpecifier; - if(m_storageSpecifier.get()) m_storageSpecifier->setParent(this); -} - -void SimpleDeclarationAST::setTypeSpec(TypeSpecifierAST::Node& typeSpec) -{ - m_typeSpec = typeSpec; - if(m_typeSpec.get()) m_typeSpec->setParent(this); -} - -void SimpleDeclarationAST::setInitDeclaratorList(InitDeclaratorListAST::Node& initDeclaratorList) -{ - m_initDeclaratorList = initDeclaratorList; - if(m_initDeclaratorList.get()) m_initDeclaratorList->setParent(this); -} - -void SimpleDeclarationAST::setWinDeclSpec(GroupAST::Node& winDeclSpec) -{ - m_winDeclSpec = winDeclSpec; - if(m_winDeclSpec.get()) m_winDeclSpec->setParent(this); -} - - -// ------------------------------------------------------------------------ - -InitDeclaratorListAST::InitDeclaratorListAST() -{ -} - -void InitDeclaratorListAST::addInitDeclarator(InitDeclaratorAST::Node& decl) -{ - if(!decl.get()) - return; - - decl->setParent(this); - m_initDeclaratorList.append(decl.release()); -} - -// ------------------------------------------------------------------------ - -DeclaratorAST::DeclaratorAST() -{ -} - -void DeclaratorAST::setSubDeclarator(DeclaratorAST::Node& subDeclarator) -{ - m_subDeclarator = subDeclarator; - if(m_subDeclarator.get()) m_subDeclarator->setParent(this); -} - -void DeclaratorAST::setDeclaratorId(NameAST::Node& declaratorId) -{ - m_declaratorId = declaratorId; - if(m_declaratorId.get()) m_declaratorId->setParent(this); -} - -void DeclaratorAST::setBitfieldInitialization(AST::Node& bitfieldInitialization) -{ - m_bitfieldInitialization = bitfieldInitialization; - if(m_bitfieldInitialization.get()) m_bitfieldInitialization->setParent(this); -} - -void DeclaratorAST::addArrayDimension(AST::Node& arrayDimension) -{ - if(!arrayDimension.get()) - return; - - arrayDimension->setParent(this); - m_arrayDimensionList.append(arrayDimension.release()); -} - -void DeclaratorAST::setParameterDeclarationClause(AUTO_PTR& parameterDeclarationClause) -{ - m_parameterDeclarationClause = parameterDeclarationClause; - if(m_parameterDeclarationClause.get()) m_parameterDeclarationClause->setParent(this); -} - -void DeclaratorAST::setConstant(AST::Node& constant) -{ - m_constant = constant; - if(m_constant.get()) m_constant->setParent(this); -} - -void DeclaratorAST::setExceptionSpecification(GroupAST::Node& exceptionSpecification) -{ - m_exceptionSpecification = exceptionSpecification; - if(m_exceptionSpecification.get()) m_exceptionSpecification->setParent(this); -} - -void DeclaratorAST::addPtrOp(AST::Node& ptrOp) -{ - if(!ptrOp.get()) - return; - - ptrOp->setParent(this); - m_ptrOpList.append(ptrOp.release()); -} - -// -------------------------------------------------------------------------- - -InitDeclaratorAST::InitDeclaratorAST() -{ -} - -void InitDeclaratorAST::setDeclarator(DeclaratorAST::Node& declarator) -{ - m_declarator = declarator; - if(m_declarator.get()) m_declarator->setParent(this); -} - -void InitDeclaratorAST::setInitializer(AST::Node& initializer) -{ - m_initializer = initializer; - if(m_initializer.get()) m_initializer->setParent(this); -} - -// -------------------------------------------------------------------------- - -FunctionDefinitionAST::FunctionDefinitionAST() -{ -} - -void FunctionDefinitionAST::setFunctionSpecifier(GroupAST::Node& functionSpecifier) -{ - m_functionSpecifier = functionSpecifier; - if(m_functionSpecifier.get()) m_functionSpecifier->setParent(this); -} - -void FunctionDefinitionAST::setStorageSpecifier(GroupAST::Node& storageSpecifier) -{ - m_storageSpecifier = storageSpecifier; - if(m_storageSpecifier.get()) m_storageSpecifier->setParent(this); -} - -void FunctionDefinitionAST::setTypeSpec(TypeSpecifierAST::Node& typeSpec) -{ - m_typeSpec = typeSpec; - if(m_typeSpec.get()) m_typeSpec->setParent(this); -} - -void FunctionDefinitionAST::setInitDeclarator(InitDeclaratorAST::Node& initDeclarator) -{ - m_initDeclarator = initDeclarator; - if(m_initDeclarator.get()) m_initDeclarator->setParent(this); -} - -void FunctionDefinitionAST::setFunctionBody(StatementListAST::Node& functionBody) -{ - m_functionBody = functionBody; - if(m_functionBody.get()) m_functionBody->setParent(this); -} - -void FunctionDefinitionAST::setWinDeclSpec(GroupAST::Node& winDeclSpec) -{ - m_winDeclSpec = winDeclSpec; - if(m_winDeclSpec.get()) m_winDeclSpec->setParent(this); -} - -// -------------------------------------------------------------------------- - -StatementListAST::StatementListAST() -{ -} - -void StatementListAST::addStatement(StatementAST::Node& statement) -{ - if(!statement.get()) - return; - - statement->setParent(this); - m_statementList.append(statement.release()); -} - -// -------------------------------------------------------------------------- - -IfStatementAST::IfStatementAST() -{ -} - -void IfStatementAST::setCondition(ConditionAST::Node& condition) -{ - m_condition = condition; - if(m_condition.get()) m_condition->setParent(this); -} - -void IfStatementAST::setStatement(StatementAST::Node& statement) -{ - m_statement = statement; - if(m_statement.get()) m_statement->setParent(this); -} - -void IfStatementAST::setElseStatement(StatementAST::Node& elseStatement) -{ - m_elseStatement = elseStatement; - if(m_elseStatement.get()) m_elseStatement->setParent(this); -} - -// -------------------------------------------------------------------------- - -WhileStatementAST::WhileStatementAST() -{ -} - -void WhileStatementAST::setCondition(ConditionAST::Node& condition) -{ - m_condition = condition; - if(m_condition.get()) m_condition->setParent(this); -} - -void WhileStatementAST::setStatement(StatementAST::Node& statement) -{ - m_statement = statement; - if(m_statement.get()) m_statement->setParent(this); -} - -// -------------------------------------------------------------------------- - -DoStatementAST::DoStatementAST() -{ -} - -void DoStatementAST::setCondition(ConditionAST::Node& condition) -{ - m_condition = condition; - if(m_condition.get()) m_condition->setParent(this); -} - -void DoStatementAST::setStatement(StatementAST::Node& statement) -{ - m_statement = statement; - if(m_statement.get()) m_statement->setParent(this); -} - -// -------------------------------------------------------------------------- - -ForStatementAST::ForStatementAST() -{ -} - -void ForStatementAST::setCondition(ConditionAST::Node& condition) -{ - m_condition = condition; - if(m_condition.get()) m_condition->setParent(this); -} - -void ForStatementAST::setExpression(AST::Node& expression) -{ - m_expression = expression; - if(m_expression.get()) m_expression->setParent(this); -} - -void ForStatementAST::setStatement(StatementAST::Node& statement) -{ - m_statement = statement; - if(m_statement.get()) m_statement->setParent(this); -} - -void ForStatementAST::setInitStatement(StatementAST::Node& initStatement) -{ - m_initStatement = initStatement; - if(m_initStatement.get()) m_initStatement->setParent(this); -} - -// -------------------------------------------------------------------------- - -SwitchStatementAST::SwitchStatementAST() -{ -} - -void SwitchStatementAST::setCondition(ConditionAST::Node& condition) -{ - m_condition = condition; - if(m_condition.get()) m_condition->setParent(this); -} - -void SwitchStatementAST::setStatement(StatementAST::Node& statement) -{ - m_statement = statement; - if(m_statement.get()) m_statement->setParent(this); -} - -// -------------------------------------------------------------------------- - -DeclarationStatementAST::DeclarationStatementAST() -{ -} - -void DeclarationStatementAST::setDeclaration(DeclarationAST::Node& declaration) -{ - m_declaration = declaration; - if(m_declaration.get()) m_declaration->setParent(this); -} - -// -------------------------------------------------------------------------- - -ExpressionStatementAST::ExpressionStatementAST() -{ -} - -void ExpressionStatementAST::setExpression(AST::Node& expression) -{ - m_expression = expression; - if(m_expression.get()) m_expression->setParent(this); -} - - -// -------------------------------------------------------------------------- - -ParameterDeclarationAST::ParameterDeclarationAST() -{ -} - -void ParameterDeclarationAST::setTypeSpec(TypeSpecifierAST::Node& typeSpec) -{ - m_typeSpec = typeSpec; - if(m_typeSpec.get()) m_typeSpec->setParent(this); -} - -void ParameterDeclarationAST::setDeclarator(DeclaratorAST::Node& declarator) -{ - m_declarator = declarator; - if(m_declarator.get()) m_declarator->setParent(this); -} - -void ParameterDeclarationAST::setExpression(AST::Node& expression) -{ - m_expression = expression; - if(m_expression.get()) m_expression->setParent(this); -} - -QString ParameterDeclarationAST::text() const -{ - QString str; - if(m_typeSpec.get()) - str += m_typeSpec->text() + ' '; - - if(m_declarator.get()) - str += m_declarator->text(); - - if(m_expression.get()) - str += QString(" = ") + m_expression->text(); - - return str; -} - -// -------------------------------------------------------------------------- - -ParameterDeclarationListAST::ParameterDeclarationListAST() -{ -} - -void ParameterDeclarationListAST::addParameter(ParameterDeclarationAST::Node& parameter) -{ - if(!parameter.get()) - return; - - parameter->setParent(this); - m_parameterList.append(parameter.release()); -} - -QString ParameterDeclarationListAST::text() const -{ - QStringList l; - for(int i = 0; i < m_parameterList.size(); ++i) { - l.append(m_parameterList.at(i)->text()); - } - return l.join(", "); -} - -// -------------------------------------------------------------------------- - -ParameterDeclarationClauseAST::ParameterDeclarationClauseAST() -{ -} - -void ParameterDeclarationClauseAST::setParameterDeclarationList(ParameterDeclarationListAST::Node& parameterDeclarationList) -{ - m_parameterDeclarationList = parameterDeclarationList; - if(m_parameterDeclarationList.get()) m_parameterDeclarationList->setParent(this); -} - -void ParameterDeclarationClauseAST::setEllipsis(AST::Node& ellipsis) -{ - m_ellipsis = ellipsis; - if(m_ellipsis.get()) m_ellipsis->setParent(this); -} - -QString ParameterDeclarationClauseAST::text() const -{ - QString str; - - if(m_parameterDeclarationList.get()) - str += m_parameterDeclarationList->text(); - - if(m_ellipsis.get()) - str += " ..."; - - return str; -} - -// -------------------------------------------------------------------------- - -GroupAST::GroupAST() -{ -} - -void GroupAST::addNode(AST::Node& node) -{ - if(!node.get()) - return; - - node->setParent(this); - m_nodeList.append(node.release()); -} - -QString GroupAST::text() const -{ - QStringList l; - for(int i = 0; i < m_nodeList.size(); ++i) { - l.append(m_nodeList.at(i)->text()); - } - return l.join(" "); -} - -// -------------------------------------------------------------------------- - -AccessDeclarationAST::AccessDeclarationAST() -{ -} - -void AccessDeclarationAST::addAccess(AST::Node& access) -{ - if(!access.get()) - return; - - access->setParent(this); - m_accessList.append(access.release()); -} - -QString AccessDeclarationAST::text() const -{ - QStringList l; - for(int i = 0; i < m_accessList.size(); ++i) { - l.append(m_accessList.at(i)->text()); - } - return l.join(" "); -} - -// -------------------------------------------------------------------------- - -TypeParameterAST::TypeParameterAST() -{ -} - -void TypeParameterAST::setKind(AST::Node& kind) -{ - m_kind = kind; - if(m_kind.get()) m_kind->setParent(this); -} - -void TypeParameterAST::setTemplateParameterList(AUTO_PTR& templateParameterList) -{ - m_templateParameterList = templateParameterList; - if(m_templateParameterList.get()) m_templateParameterList->setParent(this); -} - -void TypeParameterAST::setName(NameAST::Node& name) -{ - m_name = name; - if(m_name.get()) m_name->setParent(this); -} - -void TypeParameterAST::setTypeId(AST::Node& typeId) -{ - m_typeId = typeId; - if(m_typeId.get()) m_typeId->setParent(this); -} - -// -------------------------------------------------------------------------- - -TemplateParameterAST::TemplateParameterAST() -{ -} - -void TemplateParameterAST::setTypeParameter(TypeParameterAST::Node& typeParameter) -{ - m_typeParameter = typeParameter; - if(m_typeParameter.get()) m_typeParameter->setParent(this); -} - -void TemplateParameterAST::setTypeValueParameter(ParameterDeclarationAST::Node& typeValueParameter) -{ - m_typeValueParameter = typeValueParameter; - if(m_typeValueParameter.get()) m_typeValueParameter->setParent(this); -} - -// -------------------------------------------------------------------------- - -TemplateParameterListAST::TemplateParameterListAST() -{ -} - -void TemplateParameterListAST::addTemplateParameter(TemplateParameterAST::Node& templateParameter) -{ - if(!templateParameter.get()) - return; - - templateParameter->setParent(this); - m_templateParameterList.append(templateParameter.release()); -} - -// -------------------------------------------------------------------------- - -ConditionAST::ConditionAST() -{ -} - -void ConditionAST::setTypeSpec(TypeSpecifierAST::Node& typeSpec) -{ - m_typeSpec = typeSpec; - if(m_typeSpec.get()) m_typeSpec->setParent(this); -} - -void ConditionAST::setDeclarator(DeclaratorAST::Node& declarator) -{ - m_declarator = declarator; - if(m_declarator.get()) m_declarator->setParent(this); -} - -void ConditionAST::setExpression(AST::Node& expression) -{ - m_expression = expression; - if(m_expression.get()) m_expression->setParent(this); -} - -void ClassSpecifierAST::setWinDeclSpec(GroupAST::Node & winDeclSpec) -{ - m_winDeclSpec = winDeclSpec; - if(m_winDeclSpec.get()) m_winDeclSpec->setParent(this); -} diff -Nru umbrello-4.12.3/umbrello/codeimport/kdevcppparser/ast.h umbrello-4.12.90/umbrello/codeimport/kdevcppparser/ast.h --- umbrello-4.12.3/umbrello/codeimport/kdevcppparser/ast.h 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/codeimport/kdevcppparser/ast.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,1463 +0,0 @@ -/* This file is part of KDevelop - Copyright (C) 2002, 2003 Roberto Raggi - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef AST_H -#define AST_H - -#include "position.h" -#include -#include -#include - -#if defined(Q_OS_WIN32) || defined(Q_CC_SUN) - -#ifndef _THROW0 -# define _THROW0() -#endif - -template class AUTO_PTR { -private: - _Tp* _M_ptr; - -public: - typedef _Tp element_type; - - explicit AUTO_PTR(_Tp* __p = 0) _THROW0() : _M_ptr(__p) {} - - template AUTO_PTR(AUTO_PTR<_Tp1>& __a) _THROW0() - : _M_ptr(__a.release()) {} - - AUTO_PTR(AUTO_PTR& __a) _THROW0() : _M_ptr(__a.release()) {} - - - - template - AUTO_PTR& operator=(AUTO_PTR<_Tp1>& __a) _THROW0() { - if (__a.get() != this->get()) { - delete _M_ptr; - _M_ptr = __a.release(); - } - return *this; - } - - AUTO_PTR& operator=(AUTO_PTR& __a) _THROW0() { - if (&__a != this) { - delete _M_ptr; - _M_ptr = __a.release(); - } - return *this; - } - - ~AUTO_PTR() _THROW0() { delete _M_ptr; } - - _Tp& operator*() const _THROW0() { - return *_M_ptr; - } - _Tp* operator->() const _THROW0() { - return _M_ptr; - } - _Tp* get() const _THROW0() { - return _M_ptr; - } - _Tp* release() _THROW0() { - _Tp* __tmp = _M_ptr; - _M_ptr = 0; - return __tmp; - } - void reset(_Tp* __p = 0) _THROW0() { - delete _M_ptr; - _M_ptr = __p; - } - - // According to the C++ standard, these conversions are required. Most - // present-day compilers, however, do not enforce that requirement---and, - // in fact, most present-day compilers do not support the language - // features that these conversions rely on. - - -private: - template struct AUTO_PTR_ref { - _Tp1* _M_ptr; - AUTO_PTR_ref(_Tp1* __p) : _M_ptr(__p) {} - }; - -public: - AUTO_PTR(AUTO_PTR_ref<_Tp> __ref) _THROW0() - : _M_ptr(__ref._M_ptr) {} - template operator AUTO_PTR_ref<_Tp1>() _THROW0() - { return AUTO_PTR_ref<_Tp>(this->release()); } - template operator AUTO_PTR<_Tp1>() _THROW0() - { return AUTO_PTR<_Tp1>(this->release()); } - -}; - -#else -#define AUTO_PTR std::auto_ptr -#endif - -template typename T::Node CreateNode() -{ - typename T::Node node(new T); - node->setNodeType(T::Type); - return node; -} - -template typename T::Node NullNode() -{ - typename T::Node node; - return node; -} - -enum NodeType - { - NodeType_Generic = 0, - - NodeType_TemplateArgumentList = 1000, - NodeType_ClassOrNamespaceName, - NodeType_Name, - NodeType_Declaration, - NodeType_TypeSpecifier, - NodeType_BaseSpecifier, - NodeType_BaseClause, - NodeType_ClassSpecifier, - NodeType_Enumerator, - NodeType_EnumSpecifier, - NodeType_ElaboratedTypeSpecifier, - NodeType_LinkageBody, - NodeType_LinkageSpecification, - NodeType_Namespace, - NodeType_NamespaceAlias, - NodeType_Using, - NodeType_UsingDirective, - NodeType_InitDeclaratorList, - NodeType_Typedef, - NodeType_Declarator, - NodeType_InitDeclarator, - NodeType_TemplateDeclaration, - NodeType_SimpleDeclaration, - NodeType_Statement, - NodeType_StatementList, - NodeType_IfStatement, - NodeType_WhileStatement, - NodeType_DoStatement, - NodeType_ForStatement, - NodeType_SwitchStatement, - NodeType_DeclarationStatement, - NodeType_TranslationUnit, - NodeType_FunctionDefinition, - NodeType_ExpressionStatement, - NodeType_ParameterDeclaration, - NodeType_ParameterDeclarationList, - NodeType_ParameterDeclarationClause, - NodeType_Group, - NodeType_AccessDeclaration, - NodeType_TypeParameter, - NodeType_TemplateParameter, - NodeType_TemplateParameterList, - NodeType_Condition, - NodeType_File, - - NodeType_Custom = 2000 - }; - -QString nodeTypeToString(int type); - - -#if defined(CPPPARSER_QUICK_ALLOCATOR) - -#include - -#define DECLARE_ALLOC(tp) \ - void * operator new(std::size_t) \ - { \ - return quick_allocator< tp >::alloc(); \ - } \ - \ - void operator delete(void * p) \ - { \ - quick_allocator< tp >::dealloc(p); \ - } -#else - -#define DECLARE_ALLOC(tp) - -#endif - -class AST -{ -public: - typedef AUTO_PTR Node; - enum { Type=NodeType_Generic }; - - DECLARE_ALLOC(AST) - -public: - AST(); - virtual ~AST(); - - int nodeType() const { return m_nodeType; } - void setNodeType(int nodeType) { m_nodeType = nodeType; } - - AST* parent() { return m_parent; } - void setParent(AST* parent); - - void setStartPosition(Position const& p); - Position const& getStartPosition() const; - - void setEndPosition(Position const& p); - Position const& getEndPosition() const; - -#ifndef CPPPARSER_NO_CHILDREN - QList children() { return m_children; } - void appendChild(AST* child); - void removeChild(AST* child); -#endif - - virtual inline QString text() const - { return m_slice; } - - QString comment() const - { return m_comment; } - - inline void setSlice(const QString& slice) - { m_slice = slice; } - - inline void setSlice(const QString &text, int position, int length) - { - m_slice = text.mid(position, length); - } - - inline void setText(const QString &text) - { setSlice(text, 0, text.length()); } - - void setComment(const QString &comment) - { m_comment = comment; } - -private: - int m_nodeType; - AST* m_parent; - Position m_startPosition, m_endPosition; - QString m_slice; -#ifndef CPPPARSER_NO_CHILDREN - QList m_children; -#endif - QString m_comment; - -private: - AST(const AST& source); - void operator = (const AST& source); -}; - -class GroupAST: public AST -{ -public: - typedef AUTO_PTR Node; - enum { Type = NodeType_Group }; - - DECLARE_ALLOC(GroupAST) - - public: - GroupAST(); - - QList nodeList() { return m_nodeList; } - void addNode(AST::Node& node); - - virtual QString text() const; - -private: - QList m_nodeList; - -private: - GroupAST(const GroupAST& source); - void operator = (const GroupAST& source); -}; - - -class TemplateArgumentListAST: public AST -{ -public: - typedef AUTO_PTR Node; - enum { Type = NodeType_TemplateArgumentList }; - - DECLARE_ALLOC(TemplateArgumentListAST) - - public: - TemplateArgumentListAST(); - - void addArgument(AST::Node& arg); - QList argumentList() { return m_argumentList; } - - virtual QString text() const; - -private: - QList m_argumentList; - -private: - TemplateArgumentListAST(const TemplateArgumentListAST& source); - void operator = (const TemplateArgumentListAST& source); -}; - -class ClassOrNamespaceNameAST: public AST -{ -public: - typedef AUTO_PTR Node; - enum { Type = NodeType_ClassOrNamespaceName }; - - DECLARE_ALLOC(ClassOrNamespaceNameAST) - - public: - ClassOrNamespaceNameAST(); - - AST* name() { return m_name.get(); } - void setName(AST::Node& name); - - TemplateArgumentListAST* templateArgumentList() { return m_templateArgumentList.get(); } - void setTemplateArgumentList(TemplateArgumentListAST::Node& templateArgumentList); - - virtual QString text() const; - -private: - AST::Node m_name; - TemplateArgumentListAST::Node m_templateArgumentList; - -private: - ClassOrNamespaceNameAST(const ClassOrNamespaceNameAST& source); - void operator = (const ClassOrNamespaceNameAST& source); -}; - -class NameAST: public AST -{ -public: - typedef AUTO_PTR Node; - enum { Type = NodeType_Name }; - - DECLARE_ALLOC(NameAST) - - public: - NameAST(); - - bool isGlobal() const { return m_global; } - void setGlobal(bool b); - - void addClassOrNamespaceName(ClassOrNamespaceNameAST::Node& classOrNamespaceName); - QList classOrNamespaceNameList() { return m_classOrNamespaceNameList; } - - ClassOrNamespaceNameAST* unqualifiedName() { return m_unqualifiedName.get(); } - void setUnqualifiedName(ClassOrNamespaceNameAST::Node& unqualifiedName); - - virtual QString text() const; - -private: - bool m_global; - ClassOrNamespaceNameAST::Node m_unqualifiedName; - QList m_classOrNamespaceNameList; - -private: - NameAST(const NameAST& source); - void operator = (const NameAST& source); -}; - -class TypeParameterAST: public AST -{ -public: - typedef AUTO_PTR Node; - enum { Type = NodeType_TypeParameter }; - - DECLARE_ALLOC(TypeParameterAST) - - public: - TypeParameterAST(); - - AST* kind() { return m_kind.get(); } - void setKind(AST::Node& kind); - - class TemplateParameterListAST* templateParameterList() { return m_templateParameterList.get(); } - void setTemplateParameterList(AUTO_PTR& templateParameterList); - - NameAST* name() { return m_name.get(); } - void setName(NameAST::Node& name); - - AST* typeId() { return m_typeId.get(); } - void setTypeId(AST::Node& typeId); - -private: - AST::Node m_kind; - AUTO_PTR m_templateParameterList; - NameAST::Node m_name; - AST::Node m_typeId; - -private: - TypeParameterAST(const TypeParameterAST& source); - void operator = (const TypeParameterAST& source); -}; - -class DeclarationAST: public AST -{ -public: - typedef AUTO_PTR Node; - enum { Type = NodeType_Declaration }; - - DECLARE_ALLOC(DeclarationAST) - - public: - DeclarationAST(); - -private: - DeclarationAST(const DeclarationAST& source); - void operator = (const DeclarationAST& source); -}; - -class FileAST: public DeclarationAST -{ -public: - typedef AUTO_PTR Node; - enum { Type = NodeType_File }; - - DECLARE_ALLOC(FileAST) - - public: - FileAST(); - - QString fileName() { return m_fileName; } - void setFileName(QString fileName) { m_fileName = fileName; } - - QList nodeList() { return m_nodeList; } - void addNode(AST::Node& node); - -private: - QList m_nodeList; - QString m_fileName; - -private: - FileAST(const FileAST& source); - void operator = (const FileAST& source); -}; - -class AccessDeclarationAST: public DeclarationAST -{ -public: - typedef AUTO_PTR Node; - enum { Type = NodeType_AccessDeclaration }; - - DECLARE_ALLOC(AccessDeclarationAST) - - public: - AccessDeclarationAST(); - - QList accessList() { return m_accessList; } - void addAccess(AST::Node& access); - - virtual QString text() const; - -private: - QList m_accessList; - -private: - AccessDeclarationAST(const AccessDeclarationAST& source); - void operator = (const AccessDeclarationAST& source); -}; - -class TypeSpecifierAST: public AST -{ -public: - typedef AUTO_PTR Node; - enum { Type = NodeType_TypeSpecifier }; - - DECLARE_ALLOC(TypeSpecifierAST) - - public: - TypeSpecifierAST(); - - virtual NameAST* name() { return m_name.get(); } - virtual void setName(NameAST::Node& name); - - GroupAST* cvQualify() { return m_cvQualify.get(); } - void setCvQualify(GroupAST::Node& cvQualify); - - GroupAST* cv2Qualify() { return m_cv2Qualify.get(); } - void setCv2Qualify(GroupAST::Node& cv2Qualify); - - virtual QString text() const; - -private: - NameAST::Node m_name; - GroupAST::Node m_cvQualify; - GroupAST::Node m_cv2Qualify; - -private: - TypeSpecifierAST(const TypeSpecifierAST& source); - void operator = (const TypeSpecifierAST& source); -}; - -class BaseSpecifierAST: public AST -{ -public: - typedef AUTO_PTR Node; - enum { Type = NodeType_BaseSpecifier }; - - DECLARE_ALLOC(BaseSpecifierAST) - - public: - BaseSpecifierAST(); - - AST* isVirtual() { return m_isVirtual.get(); } - void setIsVirtual(AST::Node& isVirtual); - - AST* access() { return m_access.get(); } - void setAccess(AST::Node& access); - - NameAST* name() { return m_name.get(); } - void setName(NameAST::Node& name); - -private: - AST::Node m_isVirtual; - AST::Node m_access; - NameAST::Node m_name; - -private: - BaseSpecifierAST(const BaseSpecifierAST& source); - void operator = (const BaseSpecifierAST& source); -}; - -class BaseClauseAST: public AST -{ -public: - typedef AUTO_PTR Node; - enum { Type = NodeType_BaseClause }; - - DECLARE_ALLOC(BaseClauseAST) - - public: - BaseClauseAST(); - - void addBaseSpecifier(BaseSpecifierAST::Node& baseSpecifier); - QList baseSpecifierList() { return m_baseSpecifierList; } - -private: - QList m_baseSpecifierList; - -private: - BaseClauseAST(const BaseClauseAST& source); - void operator = (const BaseClauseAST& source); -}; - -class ClassSpecifierAST: public TypeSpecifierAST -{ -public: - typedef AUTO_PTR Node; - enum { Type = NodeType_ClassSpecifier }; - - DECLARE_ALLOC(ClassSpecifierAST) - - public: - ClassSpecifierAST(); - - GroupAST* winDeclSpec() { return m_winDeclSpec.get(); } - void setWinDeclSpec(GroupAST::Node& winDeclSpec); - - AST* classKey() { return m_classKey.get(); } - void setClassKey(AST::Node& classKey); - - BaseClauseAST* baseClause() { return m_baseClause.get(); } - void setBaseClause(BaseClauseAST::Node& baseClause); - - QList declarationList() { return m_declarationList; } - void addDeclaration(DeclarationAST::Node& declaration); - -private: - GroupAST::Node m_winDeclSpec; - AST::Node m_classKey; - BaseClauseAST::Node m_baseClause; - QList m_declarationList; - -private: - ClassSpecifierAST(const ClassSpecifierAST& source); - void operator = (const ClassSpecifierAST& source); -}; - -class EnumeratorAST: public AST -{ -public: - typedef AUTO_PTR Node; - enum { Type = NodeType_Enumerator }; - - DECLARE_ALLOC(EnumeratorAST) - - public: - EnumeratorAST(); - - AST* id() { return m_id.get(); } - void setId(AST::Node& id); - - AST* expr() { return m_expr.get(); } - void setExpr(AST::Node& expr); - -private: - AST::Node m_id; - AST::Node m_expr; - -private: - EnumeratorAST(const EnumeratorAST& source); - void operator = (const EnumeratorAST& source); -}; - -class EnumSpecifierAST: public TypeSpecifierAST -{ -public: - typedef AUTO_PTR Node; - enum { Type = NodeType_EnumSpecifier }; - - DECLARE_ALLOC(EnumSpecifierAST) - - public: - EnumSpecifierAST(); - - void addEnumerator(EnumeratorAST::Node& enumerator); - QList enumeratorList() { return m_enumeratorList; } - -private: - QList m_enumeratorList; - -private: - EnumSpecifierAST(const EnumSpecifierAST& source); - void operator = (const EnumSpecifierAST& source); -}; - -class ElaboratedTypeSpecifierAST: public TypeSpecifierAST -{ -public: - typedef AUTO_PTR Node; - enum { Type = NodeType_ElaboratedTypeSpecifier }; - - DECLARE_ALLOC(ElaboratedTypeSpecifierAST) - - public: - ElaboratedTypeSpecifierAST(); - - AST* kind() { return m_kind.get(); } - void setKind(AST::Node& kind); - - virtual QString text() const; - -private: - AST::Node m_kind; - -private: - ElaboratedTypeSpecifierAST(const ElaboratedTypeSpecifierAST& source); - void operator = (const ElaboratedTypeSpecifierAST& source); -}; - -class LinkageBodyAST: public AST -{ -public: - typedef AUTO_PTR Node; - enum { Type = NodeType_LinkageBody }; - - DECLARE_ALLOC(LinkageBodyAST) - - public: - LinkageBodyAST(); - - void addDeclaration(DeclarationAST::Node& ast); - QList declarationList() { return m_declarationList; } - -private: - QList m_declarationList; - -private: - LinkageBodyAST(const LinkageBodyAST& source); - void operator = (const LinkageBodyAST& source); -}; - -class LinkageSpecificationAST: public DeclarationAST -{ -public: - typedef AUTO_PTR Node; - enum { Type = NodeType_LinkageSpecification }; - - DECLARE_ALLOC(LinkageSpecificationAST) - - public: - LinkageSpecificationAST(); - - AST* externType() { return m_externType.get(); } - void setExternType(AST::Node& externType); - - LinkageBodyAST* linkageBody() { return m_linkageBody.get(); } - void setLinkageBody(LinkageBodyAST::Node& linkageBody); - - DeclarationAST* declaration() { return m_declaration.get(); } - void setDeclaration(DeclarationAST::Node& decl); - -private: - AST::Node m_externType; - LinkageBodyAST::Node m_linkageBody; - DeclarationAST::Node m_declaration; - -private: - LinkageSpecificationAST(const LinkageSpecificationAST& source); - void operator = (const LinkageSpecificationAST& source); -}; - -class NamespaceAST: public DeclarationAST -{ -public: - typedef AUTO_PTR Node; - enum { Type = NodeType_Namespace }; - - DECLARE_ALLOC(NamespaceAST) - - public: - NamespaceAST(); - - AST* namespaceName() { return m_namespaceName.get(); } - void setNamespaceName(AST::Node& namespaceName); - - LinkageBodyAST* linkageBody() { return m_linkageBody.get(); } - void setLinkageBody(LinkageBodyAST::Node& linkageBody); - -private: - AST::Node m_namespaceName; - LinkageBodyAST::Node m_linkageBody; - -private: - NamespaceAST(const NamespaceAST& source); - void operator = (const NamespaceAST& source); -}; - -class NamespaceAliasAST: public DeclarationAST -{ -public: - typedef AUTO_PTR Node; - enum { Type = NodeType_NamespaceAlias }; - - DECLARE_ALLOC(NamespaceAliasAST) - - public: - NamespaceAliasAST(); - - AST* namespaceName() { return m_namespaceName.get(); } - void setNamespaceName(AST::Node& name); - - NameAST* aliasName() { return m_aliasName.get(); } - void setAliasName(NameAST::Node& name); - -private: - AST::Node m_namespaceName; - NameAST::Node m_aliasName; - -private: - NamespaceAliasAST(const NamespaceAliasAST& source); - void operator = (const NamespaceAliasAST& source); -}; - -class UsingAST: public DeclarationAST -{ -public: - typedef AUTO_PTR Node; - enum { Type = NodeType_Using }; - - DECLARE_ALLOC(UsingAST) - - public: - UsingAST(); - - AST* typeName() { return m_typeName.get(); } - void setTypeName(AST::Node& typeName); - - NameAST* name() { return m_name.get(); } - void setName(NameAST::Node& name); - -private: - AST::Node m_typeName; - NameAST::Node m_name; - -private: - UsingAST(const UsingAST& source); - void operator = (const UsingAST& source); -}; - -class UsingDirectiveAST: public DeclarationAST -{ -public: - typedef AUTO_PTR Node; - enum { Type = NodeType_UsingDirective }; - - DECLARE_ALLOC(UsingDirectiveAST) - - public: - UsingDirectiveAST(); - - NameAST* name() { return m_name.get(); } - void setName(NameAST::Node& name); - -private: - NameAST::Node m_name; - -private: - UsingDirectiveAST(const UsingDirectiveAST& source); - void operator = (const UsingDirectiveAST& source); -}; - -class DeclaratorAST: public AST -{ -public: - typedef AUTO_PTR Node; - enum { Type = NodeType_Declarator }; - - DECLARE_ALLOC(DeclaratorAST) - - public: - DeclaratorAST(); - - QList ptrOpList() { return m_ptrOpList; } - void addPtrOp(AST::Node& ptrOp); - - DeclaratorAST* subDeclarator() { return m_subDeclarator.get(); } - void setSubDeclarator(Node& subDeclarator); - - NameAST* declaratorId() { return m_declaratorId.get(); } - void setDeclaratorId(NameAST::Node& declaratorId); - - AST* bitfieldInitialization() { return m_bitfieldInitialization.get(); } - void setBitfieldInitialization(AST::Node& bitfieldInitialization); - - QList arrayDimensionList() { return m_arrayDimensionList; } - void addArrayDimension(AST::Node& arrayDimension); - - class ParameterDeclarationClauseAST* parameterDeclarationClause() { return m_parameterDeclarationClause.get(); } - void setParameterDeclarationClause(AUTO_PTR& parameterDeclarationClause); - - // ### replace 'constant' with cvQualify - AST* constant() { return m_constant.get(); } - void setConstant(AST::Node& constant); - - GroupAST* exceptionSpecification() { return m_exceptionSpecification.get(); } - void setExceptionSpecification(GroupAST::Node& exceptionSpecification); - -private: - QList m_ptrOpList; - Node m_subDeclarator; - NameAST::Node m_declaratorId; - AST::Node m_bitfieldInitialization; - QList m_arrayDimensionList; - AUTO_PTR m_parameterDeclarationClause; - AST::Node m_constant; - GroupAST::Node m_exceptionSpecification; - -private: - DeclaratorAST(const DeclaratorAST& source); - void operator = (const DeclaratorAST& source); -}; - -class ParameterDeclarationAST: public AST -{ -public: - typedef AUTO_PTR Node; - enum { Type = NodeType_ParameterDeclaration }; - - DECLARE_ALLOC(ParameterDeclarationAST) - - public: - ParameterDeclarationAST(); - - TypeSpecifierAST* typeSpec() { return m_typeSpec.get(); } - void setTypeSpec(TypeSpecifierAST::Node& typeSpec); - - DeclaratorAST* declarator() { return m_declarator.get(); } - void setDeclarator(DeclaratorAST::Node& declarator); - - AST* expression() { return m_expression.get(); } - void setExpression(AST::Node& expression); - - virtual QString text() const; - -private: - TypeSpecifierAST::Node m_typeSpec; - DeclaratorAST::Node m_declarator; - AST::Node m_expression; - -private: - ParameterDeclarationAST(const ParameterDeclarationAST& source); - void operator = (const ParameterDeclarationAST& source); -}; - -class ParameterDeclarationListAST: public AST -{ -public: - typedef AUTO_PTR Node; - enum { Type = NodeType_ParameterDeclarationList }; - - DECLARE_ALLOC(ParameterDeclarationListAST) - - public: - ParameterDeclarationListAST(); - - QList parameterList() { return m_parameterList; } - void addParameter(ParameterDeclarationAST::Node& parameter); - - virtual QString text() const; - -private: - QList m_parameterList; - -private: - ParameterDeclarationListAST(const ParameterDeclarationListAST& source); - void operator = (const ParameterDeclarationListAST& source); -}; - -class ParameterDeclarationClauseAST: public AST -{ -public: - typedef AUTO_PTR Node; - enum { Type = NodeType_ParameterDeclarationClause }; - - DECLARE_ALLOC(ParameterDeclarationClauseAST) - - public: - ParameterDeclarationClauseAST(); - - ParameterDeclarationListAST* parameterDeclarationList() { return m_parameterDeclarationList.get(); } - void setParameterDeclarationList(ParameterDeclarationListAST::Node& parameterDeclarationList); - - AST* ellipsis() { return m_ellipsis.get(); } - void setEllipsis(AST::Node& ellipsis); - - virtual QString text() const; - -private: - ParameterDeclarationListAST::Node m_parameterDeclarationList; - AST::Node m_ellipsis; - -private: - ParameterDeclarationClauseAST(const ParameterDeclarationClauseAST& source); - void operator = (const ParameterDeclarationClauseAST& source); -}; - - -class InitDeclaratorAST: public AST -{ -public: - typedef AUTO_PTR Node; - enum { Type = NodeType_InitDeclarator }; - - DECLARE_ALLOC(InitDeclaratorAST) - - public: - InitDeclaratorAST(); - - DeclaratorAST* declarator() { return m_declarator.get(); } - void setDeclarator(DeclaratorAST::Node& declarator); - - AST* initializer() { return m_initializer.get(); } - void setInitializer(AST::Node& initializer); - -private: - DeclaratorAST::Node m_declarator; - AST::Node m_initializer; - -private: - InitDeclaratorAST(const InitDeclaratorAST& source); - void operator = (const InitDeclaratorAST& source); -}; - -class InitDeclaratorListAST: public AST -{ -public: - typedef AUTO_PTR Node; - enum { Type = NodeType_InitDeclaratorList }; - - DECLARE_ALLOC(InitDeclaratorListAST) - - public: - InitDeclaratorListAST(); - - QList initDeclaratorList() { return m_initDeclaratorList; } - void addInitDeclarator(InitDeclaratorAST::Node& decl); - -private: - QList m_initDeclaratorList; - -private: - InitDeclaratorListAST(const InitDeclaratorListAST& source); - void operator = (const InitDeclaratorListAST& source); -}; - -class TypedefAST: public DeclarationAST -{ -public: - typedef AUTO_PTR Node; - enum { Type = NodeType_Typedef }; - - DECLARE_ALLOC(TypedefAST) - - public: - TypedefAST(); - - TypeSpecifierAST* typeSpec() { return m_typeSpec.get(); } - void setTypeSpec(TypeSpecifierAST::Node& typeSpec); - - InitDeclaratorListAST* initDeclaratorList() { return m_initDeclaratorList.get(); } - void setInitDeclaratorList(InitDeclaratorListAST::Node& initDeclaratorList); - -private: - TypeSpecifierAST::Node m_typeSpec; - InitDeclaratorListAST::Node m_initDeclaratorList; - -private: - TypedefAST(const TypedefAST& source); - void operator = (const TypedefAST& source); -}; - -class TemplateParameterAST: public AST -{ -public: - typedef AUTO_PTR Node; - enum { Type = NodeType_TemplateParameter }; - - DECLARE_ALLOC(TemplateParameterAST) - - public: - TemplateParameterAST(); - - TypeParameterAST* typeParameter() { return m_typeParameter.get(); } - void setTypeParameter(TypeParameterAST::Node& typeParameter); - - ParameterDeclarationAST* typeValueParameter() { return m_typeValueParameter.get(); } - void setTypeValueParameter(ParameterDeclarationAST::Node& typeValueParameter); - -private: - TypeParameterAST::Node m_typeParameter; - ParameterDeclarationAST::Node m_typeValueParameter; - -private: - TemplateParameterAST(const TemplateParameterAST& source); - void operator = (const TemplateParameterAST& source); -}; - -class TemplateParameterListAST: public AST -{ -public: - typedef AUTO_PTR Node; - enum { Type = NodeType_TemplateParameterList }; - - DECLARE_ALLOC(TemplateParameterListAST) - - public: - TemplateParameterListAST(); - - QList templateParameterList() { return m_templateParameterList; } - void addTemplateParameter(TemplateParameterAST::Node& templateParameter); - -private: - QList m_templateParameterList; - -private: - TemplateParameterListAST(const TemplateParameterListAST& source); - void operator = (const TemplateParameterListAST& source); -}; - -class TemplateDeclarationAST: public DeclarationAST -{ -public: - typedef AUTO_PTR Node; - enum { Type = NodeType_TemplateDeclaration }; - - DECLARE_ALLOC(TemplateDeclarationAST) - - public: - TemplateDeclarationAST(); - - AST* exported() { return m_exported.get(); } - void setExported(AST::Node& exported); - - TemplateParameterListAST* templateParameterList() { return m_templateParameterList.get(); } - void setTemplateParameterList(TemplateParameterListAST::Node& templateParameterList); - - DeclarationAST* declaration() { return m_declaration.get(); } - void setDeclaration(DeclarationAST::Node& declaration); - -private: - AST::Node m_exported; - TemplateParameterListAST::Node m_templateParameterList; - DeclarationAST::Node m_declaration; - -private: - TemplateDeclarationAST(const TemplateDeclarationAST& source); - void operator = (const TemplateDeclarationAST& source); -}; - -class SimpleDeclarationAST: public DeclarationAST -{ -public: - typedef AUTO_PTR Node; - enum { Type = NodeType_SimpleDeclaration }; - - DECLARE_ALLOC(SimpleDeclarationAST) - - public: - SimpleDeclarationAST(); - - GroupAST* functionSpecifier() { return m_functionSpecifier.get(); } - void setFunctionSpecifier(GroupAST::Node& functionSpecifier); - - GroupAST* storageSpecifier() { return m_storageSpecifier.get(); } - void setStorageSpecifier(GroupAST::Node& storageSpecifier); - - TypeSpecifierAST* typeSpec() { return m_typeSpec.get(); } - void setTypeSpec(TypeSpecifierAST::Node& typeSpec); - - InitDeclaratorListAST* initDeclaratorList() { return m_initDeclaratorList.get(); } - void setInitDeclaratorList(InitDeclaratorListAST::Node& initDeclaratorList); - - GroupAST* winDeclSpec() { return m_winDeclSpec.get(); } - void setWinDeclSpec(GroupAST::Node& winDeclSpec); - -private: - GroupAST::Node m_functionSpecifier; - GroupAST::Node m_storageSpecifier; - TypeSpecifierAST::Node m_typeSpec; - InitDeclaratorListAST::Node m_initDeclaratorList; - GroupAST::Node m_winDeclSpec; - -private: - SimpleDeclarationAST(const SimpleDeclarationAST& source); - void operator = (const SimpleDeclarationAST& source); -}; - -class StatementAST: public AST -{ -public: - typedef AUTO_PTR Node; - enum { Type = NodeType_Statement }; - - DECLARE_ALLOC(StatementAST) - - public: - StatementAST(); - -private: - StatementAST(const StatementAST& source); - void operator = (const StatementAST& source); -}; - -class ExpressionStatementAST: public StatementAST -{ -public: - typedef AUTO_PTR Node; - enum { Type = NodeType_ExpressionStatement }; - - DECLARE_ALLOC(ExpressionStatementAST) - - public: - ExpressionStatementAST(); - - AST* expression() { return m_expression.get(); } - void setExpression(AST::Node& expression); - -private: - AST::Node m_expression; - -private: - ExpressionStatementAST(const ExpressionStatementAST& source); - void operator = (const ExpressionStatementAST& source); -}; - -class ConditionAST: public AST -{ -public: - typedef AUTO_PTR Node; - enum { Type = NodeType_Condition }; - - DECLARE_ALLOC(ConditionAST) - - public: - ConditionAST(); - - TypeSpecifierAST* typeSpec() { return m_typeSpec.get(); } - void setTypeSpec(TypeSpecifierAST::Node& typeSpec); - - DeclaratorAST* declarator() { return m_declarator.get(); } - void setDeclarator(DeclaratorAST::Node& declarator); - - AST* expression() { return m_expression.get(); } - void setExpression(AST::Node& expression); - -private: - TypeSpecifierAST::Node m_typeSpec; - DeclaratorAST::Node m_declarator; - AST::Node m_expression; - -private: - ConditionAST(const ConditionAST& source); - void operator = (const ConditionAST& source); -}; - -class IfStatementAST: public StatementAST -{ -public: - typedef AUTO_PTR Node; - enum { Type = NodeType_IfStatement }; - - DECLARE_ALLOC(IfStatementAST) - - public: - IfStatementAST(); - - ConditionAST* condition() const { return m_condition.get(); } - void setCondition(ConditionAST::Node& condition); - - StatementAST* statement() { return m_statement.get(); } - void setStatement(StatementAST::Node& statement); - - StatementAST* elseStatement() { return m_elseStatement.get(); } - void setElseStatement(StatementAST::Node& statement); - -private: - ConditionAST::Node m_condition; - StatementAST::Node m_statement; - StatementAST::Node m_elseStatement; - -private: - IfStatementAST(const IfStatementAST& source); - void operator = (const IfStatementAST& source); -}; - -class WhileStatementAST: public StatementAST -{ -public: - typedef AUTO_PTR Node; - enum { Type = NodeType_WhileStatement }; - - DECLARE_ALLOC(WhileStatementAST) - - public: - WhileStatementAST(); - - ConditionAST* condition() const { return m_condition.get(); } - void setCondition(ConditionAST::Node& condition); - - StatementAST* statement() { return m_statement.get(); } - void setStatement(StatementAST::Node& statement); - -private: - ConditionAST::Node m_condition; - StatementAST::Node m_statement; - -private: - WhileStatementAST(const WhileStatementAST& source); - void operator = (const WhileStatementAST& source); -}; - -class DoStatementAST: public StatementAST -{ -public: - typedef AUTO_PTR Node; - enum { Type = NodeType_DoStatement }; - - DECLARE_ALLOC(DoStatementAST) - - public: - DoStatementAST(); - - ConditionAST* condition() const { return m_condition.get(); } - void setCondition(ConditionAST::Node& condition); - - StatementAST* statement() { return m_statement.get(); } - void setStatement(StatementAST::Node& statement); - -private: - ConditionAST::Node m_condition; - StatementAST::Node m_statement; - -private: - DoStatementAST(const DoStatementAST& source); - void operator = (const DoStatementAST& source); -}; - -class ForStatementAST: public StatementAST -{ -public: - typedef AUTO_PTR Node; - enum { Type = NodeType_ForStatement }; - - DECLARE_ALLOC(ForStatementAST) - - public: - ForStatementAST(); - - StatementAST* initStatement() { return m_initStatement.get(); } - void setInitStatement(StatementAST::Node& statement); - - ConditionAST* condition() const { return m_condition.get(); } - void setCondition(ConditionAST::Node& condition); - - AST* expression() const { return m_expression.get(); } - void setExpression(AST::Node& expression); - - StatementAST* statement() { return m_statement.get(); } - void setStatement(StatementAST::Node& statement); - -private: - ConditionAST::Node m_condition; - StatementAST::Node m_initStatement; - StatementAST::Node m_statement; - AST::Node m_expression; - -private: - ForStatementAST(const ForStatementAST& source); - void operator = (const ForStatementAST& source); -}; - -class SwitchStatementAST: public StatementAST -{ -public: - typedef AUTO_PTR Node; - enum { Type = NodeType_SwitchStatement }; - - DECLARE_ALLOC(SwitchStatementAST) - - public: - SwitchStatementAST(); - - ConditionAST* condition() const { return m_condition.get(); } - void setCondition(ConditionAST::Node& condition); - - StatementAST* statement() { return m_statement.get(); } - void setStatement(StatementAST::Node& statement); - -private: - ConditionAST::Node m_condition; - StatementAST::Node m_statement; - -private: - SwitchStatementAST(const SwitchStatementAST& source); - void operator = (const SwitchStatementAST& source); -}; - -class StatementListAST: public StatementAST -{ -public: - typedef AUTO_PTR Node; - enum { Type = NodeType_StatementList }; - - DECLARE_ALLOC(StatementListAST) - - public: - StatementListAST(); - - QList statementList() { return m_statementList; } - void addStatement(StatementAST::Node& statement); - -private: - QList m_statementList; - -private: - StatementListAST(const StatementListAST& source); - void operator = (const StatementListAST& source); -}; - -class DeclarationStatementAST: public StatementAST -{ -public: - typedef AUTO_PTR Node; - enum { Type = NodeType_DeclarationStatement }; - - DECLARE_ALLOC(DeclarationStatementAST) - - public: - DeclarationStatementAST(); - - DeclarationAST* declaration() { return m_declaration.get(); } - void setDeclaration(DeclarationAST::Node& declaration); - -private: - DeclarationAST::Node m_declaration; - -private: - DeclarationStatementAST(const DeclarationStatementAST& source); - void operator = (const DeclarationStatementAST& source); -}; - -class FunctionDefinitionAST: public DeclarationAST -{ -public: - typedef AUTO_PTR Node; - enum { Type = NodeType_FunctionDefinition }; - - DECLARE_ALLOC(FunctionDefinitionAST) - - public: - FunctionDefinitionAST(); - - GroupAST* functionSpecifier() { return m_functionSpecifier.get(); } - void setFunctionSpecifier(GroupAST::Node& functionSpecifier); - - GroupAST* storageSpecifier() { return m_storageSpecifier.get(); } - void setStorageSpecifier(GroupAST::Node& storageSpecifier); - - TypeSpecifierAST* typeSpec() { return m_typeSpec.get(); } - void setTypeSpec(TypeSpecifierAST::Node& typeSpec); - - InitDeclaratorAST* initDeclarator() { return m_initDeclarator.get(); } - void setInitDeclarator(InitDeclaratorAST::Node& initDeclarator); - - StatementListAST* functionBody() { return m_functionBody.get(); } - void setFunctionBody(StatementListAST::Node& functionBody); - - GroupAST* winDeclSpec() { return m_winDeclSpec.get(); } - void setWinDeclSpec(GroupAST::Node& winDeclSpec); - -private: - GroupAST::Node m_functionSpecifier; - GroupAST::Node m_storageSpecifier; - TypeSpecifierAST::Node m_typeSpec; - InitDeclaratorAST::Node m_initDeclarator; - StatementListAST::Node m_functionBody; - GroupAST::Node m_winDeclSpec; - -private: - FunctionDefinitionAST(const FunctionDefinitionAST& source); - void operator = (const FunctionDefinitionAST& source); -}; - - -class TranslationUnitAST: public AST -{ -public: - typedef AUTO_PTR Node; - enum { Type = NodeType_TranslationUnit }; - - DECLARE_ALLOC(TranslationUnitAST) - - public: - TranslationUnitAST(); - - void addDeclaration(DeclarationAST::Node& ast); - QList declarationList() { return m_declarationList; } - -private: - QList m_declarationList; - -private: - TranslationUnitAST(const TranslationUnitAST& source); - void operator = (const TranslationUnitAST& source); -}; - -#endif diff -Nru umbrello-4.12.3/umbrello/codeimport/kdevcppparser/ast_utils.cpp umbrello-4.12.90/umbrello/codeimport/kdevcppparser/ast_utils.cpp --- umbrello-4.12.3/umbrello/codeimport/kdevcppparser/ast_utils.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/codeimport/kdevcppparser/ast_utils.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,157 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2002 by Roberto Raggi * - * roberto@kdevelop.org * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - ***************************************************************************/ - -#include "ast_utils.h" - -#include "ast.h" -#include "debug_utils.h" - -#include -#include - -#include - -AST* findNodeAt(AST* node, Position const& position) -{ - // uDebug() << "findNodeAt(" << node << ")"; - - if(!node) - return 0; - - Position startPosition = node->getStartPosition(); - Position endPosition = node->getEndPosition(); - - if((position >= startPosition) && (position < endPosition)) { - QList children = node->children(); - for(int i = 0; i < children.size(); ++i) { - AST* a = children.at(i); - AST* r = findNodeAt(a, position); - if(r) - return r; - } - - return node; - } - - return 0; -} - -void scopeOfNode(AST* ast, QStringList& scope) -{ - if(!ast) - return; - - if(ast->parent()) - scopeOfNode(ast->parent(), scope); - - QString s; - switch(ast->nodeType()) - { - case NodeType_ClassSpecifier: - if(((ClassSpecifierAST*)ast)->name()){ - s = ((ClassSpecifierAST*)ast)->name()->text(); - s = s.isEmpty() ? QString::fromLatin1("") : s; - scope.push_back(s); - } - break; - - case NodeType_Namespace: - { - AST* namespaceName = ((NamespaceAST*)ast)->namespaceName(); - s = namespaceName ? namespaceName->text() : QString::fromLatin1(""); - scope.push_back(s); - } - break; - - case NodeType_FunctionDefinition: - { - FunctionDefinitionAST* funDef = static_cast(ast); - DeclaratorAST* d = funDef->initDeclarator()->declarator(); - - // hotfix for bug #68726 - if (!d->declaratorId()) - break; - - QList l = d->declaratorId()->classOrNamespaceNameList(); - for(int i = 0; i < l.size(); ++i) { - AST* name = l.at(i)->name(); - scope.push_back(name->text()); - } - } - break; - - default: - break; - } -} - -QString typeSpecToString(TypeSpecifierAST* typeSpec) /// @todo remove -{ - if(!typeSpec) - return QString(); - - return typeSpec->text().replace(QRegExp(" :: "), "::"); -} - -QString declaratorToString(DeclaratorAST* declarator, const QString& scope, bool skipPtrOp) -{ - if(!declarator) - return QString(); - - QString text; - - if(!skipPtrOp){ - QList ptrOpList = declarator->ptrOpList(); - for(int i = 0; i < ptrOpList.size(); ++i) { - text += ptrOpList.at(i)->text(); - } - text += ' '; - } - - text += scope; - - if(declarator->subDeclarator()) - text += QString::fromLatin1("(") + declaratorToString(declarator->subDeclarator()) + QString::fromLatin1(")"); - - if(declarator->declaratorId()) - text += declarator->declaratorId()->text(); - - QList arrays = declarator->arrayDimensionList(); - for(int i = 0; i < arrays.size(); ++i) { - text += "[]"; - } - - if(declarator->parameterDeclarationClause()){ - text += "("; - - ParameterDeclarationListAST* l = declarator->parameterDeclarationClause()->parameterDeclarationList(); - if(l != 0){ - QList params = l->parameterList(); - for(int i = 0; i < params.size(); ++i) { - QString type = typeSpecToString(params.at(i)->typeSpec()); - text += type; - if(!type.isEmpty()) - text += ' '; - text += declaratorToString(params.at(i)->declarator()); - - if(params.at(i)) - text += ", "; - } - } - - text += ")"; - - if(declarator->constant() != 0) - text += " const"; - } - - return text.replace(QRegExp(" :: "), "::").simplified(); -} diff -Nru umbrello-4.12.3/umbrello/codeimport/kdevcppparser/ast_utils.h umbrello-4.12.90/umbrello/codeimport/kdevcppparser/ast_utils.h --- umbrello-4.12.3/umbrello/codeimport/kdevcppparser/ast_utils.h 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/codeimport/kdevcppparser/ast_utils.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2002 by Roberto Raggi * - * roberto@kdevelop.org * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - ***************************************************************************/ - -#ifndef AST_UTILS_H -#define AST_UTILS_H - -#include - -class AST; -class DeclaratorAST; -class TypeSpecifierAST; -class QStringList; - -namespace KTextEditor{ class EditInterface; } - -AST* findNodeAt(AST* unit, int line, int column); -void scopeOfNode(AST* ast, QStringList&); -QString typeSpecToString(TypeSpecifierAST* typeSpec); -QString declaratorToString(DeclaratorAST* declarator, const QString& scope = QString(), bool skipPtrOp=false); - -#endif // AST_UTILS_H diff -Nru umbrello-4.12.3/umbrello/codeimport/kdevcppparser/cpptree2uml.cpp umbrello-4.12.90/umbrello/codeimport/kdevcppparser/cpptree2uml.cpp --- umbrello-4.12.3/umbrello/codeimport/kdevcppparser/cpptree2uml.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/codeimport/kdevcppparser/cpptree2uml.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -17,7 +17,9 @@ #include "debug_utils.h" #include "ast_utils.h" #include "codeimpthread.h" +#include "driver.h" #include "import_utils.h" + // FIXME: The sole reason for the next 2 includes is parseTypedef(). // Make capsule methods in ClassImport, and remove these includes. #include "classifier.h" @@ -41,7 +43,7 @@ { } -void CppTree2Uml::parseTranslationUnit(TranslationUnitAST* ast) +void CppTree2Uml::parseTranslationUnit(const ParsedFile &file) { m_currentScope.clear(); m_currentNamespace[0] = NULL; // index 0 is reserved (always NULL) @@ -57,14 +59,9 @@ m_currentDeclarator = 0; m_anon = 0; - TreeParser::parseTranslationUnit(ast); -} + Import_Utils::createUMLObject(UMLObject::ot_Artifact, file.fileName(), 0, file->comment()); -void CppTree2Uml::parseFile(FileAST* ast) -{ - Import_Utils::createUMLObject(UMLObject::ot_Artifact, ast->fileName(), - 0, - ast->comment()); + TreeParser::parseTranslationUnit(file); } void CppTree2Uml::parseNamespace(NamespaceAST* ast) diff -Nru umbrello-4.12.3/umbrello/codeimport/kdevcppparser/cpptree2uml.h umbrello-4.12.90/umbrello/codeimport/kdevcppparser/cpptree2uml.h --- umbrello-4.12.3/umbrello/codeimport/kdevcppparser/cpptree2uml.h 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/codeimport/kdevcppparser/cpptree2uml.h 2014-03-05 15:04:09.000000000 +0000 @@ -31,12 +31,11 @@ //FileDom file() { return m_file; } // translation-unit - virtual void parseTranslationUnit(TranslationUnitAST*); + virtual void parseTranslationUnit(const ParsedFile &file); // declarations //virtual void parseDeclaration(DeclarationAST*); // use parent method //virtual void parseLinkageSpecification(LinkageSpecificationAST*); // use parent method - virtual void parseFile(FileAST* ast); virtual void parseNamespace(NamespaceAST*); //virtual void parseNamespaceAlias(NamespaceAliasAST*); // use parent method //virtual void parseUsing(UsingAST*); // use parent method diff -Nru umbrello-4.12.3/umbrello/codeimport/kdevcppparser/driver.cpp umbrello-4.12.90/umbrello/codeimport/kdevcppparser/driver.cpp --- umbrello-4.12.3/umbrello/codeimport/kdevcppparser/driver.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/codeimport/kdevcppparser/driver.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,432 +0,0 @@ -/* This file is part of KDevelop - Copyright (C) 2002, 2003 Roberto Raggi - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "driver.h" - -#include "lexer.h" -#include "parser.h" -#include "debug_utils.h" - -#include - -#include -#include -#include -#include - -class DefaultSourceProvider: public SourceProvider -{ -public: - DefaultSourceProvider() {} - - virtual QString contents(const QString& fileName) - { - QString source; - - QFile f(fileName); - if(f.open(QIODevice::ReadOnly)){ - QTextStream s(&f); - source = s.readAll(); - f.close(); - } - return source; - } - - virtual bool isModified(const QString& fileName) - { - Q_UNUSED(fileName); - return true; - } - -private: - DefaultSourceProvider(const DefaultSourceProvider& source); - void operator = (const DefaultSourceProvider& source); -}; - - -Driver::Driver() - : depresolv(false), lexer(0) -{ - m_sourceProvider = new DefaultSourceProvider(); -} - -Driver::~Driver() -{ - reset(); - delete(m_sourceProvider); -} - -SourceProvider* Driver::sourceProvider() -{ - return m_sourceProvider; -} - -void Driver::setSourceProvider(SourceProvider* sourceProvider) -{ - if(m_sourceProvider) - delete(m_sourceProvider); - m_sourceProvider = sourceProvider; -} - -void Driver::reset() -{ - m_dependences.clear(); - m_macroManager.reset(); - m_problems.clear(); - m_includePaths.clear(); - - QMapIterator it(m_parsedUnits); - while (it.hasNext()){ - it.next(); - delete(it.value()); - } - m_parsedUnits.clear(); -} - -void Driver::MacroManager::reset() -{ - m_macros.clear(); -} - -void Driver::MacroManager::removeAllMacrosInFile(const QString& fileName) -{ - /** \todo use a find */ - MacroMap::iterator l_it = m_macros.begin(); - while(l_it != m_macros.end()){ - if(l_it->second.fileName() == fileName) - m_macros.erase(l_it); - else - ++l_it; - } -} - -TranslationUnitAST::Node Driver::takeTranslationUnit(const QString& fileName) -{ - QMap::Iterator it = m_parsedUnits.find(fileName); - TranslationUnitAST::Node unit(*it); - m_parsedUnits[ fileName] = 0; - return unit; -} - -TranslationUnitAST* Driver::translationUnit(const QString& fileName) const -{ - QMap::ConstIterator it = m_parsedUnits.find(fileName); - return it != m_parsedUnits.end() ? *it : 0; -} - -void Driver::addDependence(const QString & fileName, const Dependence & dep) -{ - QFileInfo fileInfo(dep.first); - QString fn = fileInfo.absoluteFilePath(); - - if (!depresolv){ - findOrInsertDependenceList(fileName).insert(fn, dep); - return; - } - - QString file = findIncludeFile(dep); - findOrInsertDependenceList(fileName).insert(file, dep); - - if (m_parsedUnits.find(file) != m_parsedUnits.end()) - return; - - if (!QFile::exists(file)) { - Problem p("Could not find include file " + dep.first, - lexer ? lexer->currentPosition() : Position()); - addProblem(fileName, p); - return; - } - - QString cfn = m_currentFileName; - Lexer *l = lexer; - parseFile(file); - m_currentFileName = cfn; - lexer = l; -} - -void Driver::MacroManager::addMacro(const Macro & macro) -{ - m_macros.insert(MacroMap::value_type(macro.name(), macro)); -} - -void Driver::addProblem(const QString & fileName, const Problem & problem) -{ - findOrInsertProblemList(fileName).append(problem); -} - -QMap< QString, Dependence >& Driver::findOrInsertDependenceList(const QString & fileName) -{ - QMap >::Iterator it = m_dependences.find(fileName); - if(it != m_dependences.end()) - return it.value(); - - QMap l; - m_dependences.insert(fileName, l); - return m_dependences[ fileName ]; -} - -QList < Problem >& Driver::findOrInsertProblemList(const QString & fileName) -{ - QMap >::Iterator it = m_problems.find(fileName); - if(it != m_problems.end()) - return it.value(); - - QList l; - m_problems.insert(fileName, l); - return m_problems[ fileName ]; -} - -QMap< QString, Dependence > Driver::dependences(const QString & fileName) const -{ - QMap >::ConstIterator it = m_dependences.find(fileName); - if(it != m_dependences.end()) - return it.value(); - return QMap(); -} - -Driver::MacroMap const& Driver::MacroManager::macros() const -{return m_macros;} - -QList < Problem > Driver::problems(const QString & fileName) const -{ - QMap >::ConstIterator it = m_problems.find(fileName); - if(it != m_problems.end()) - return it.value(); - return QList(); -} - -bool Driver::parseFile(const QString& fileName, bool onlyPreProcess, bool force) -{ - QFileInfo fileInfo(fileName); - QString absoluteFilePath = fileInfo.absoluteFilePath(); - - QMap::Iterator it = m_parsedUnits.find(absoluteFilePath); - - if(force && it != m_parsedUnits.end()){ - takeTranslationUnit(absoluteFilePath); - } else if(it != m_parsedUnits.end() && *it != 0){ - // file already processed - return true; - } - - m_dependences.remove(fileName); - m_problems.remove(fileName); - - m_currentFileName = fileName; - - Lexer lex(this); - lexer = &lex; - setupLexer(&lex); - - if (!lex.setSource( sourceProvider()->contents(fileName), fileName)) - return false; - - if(!onlyPreProcess){ - Parser parser(this, &lex); - setupParser(&parser); - - TranslationUnitAST :: Node translationUnit; - parser.parseTranslationUnit(translationUnit); - m_parsedUnits.insert(fileName, translationUnit.release()); - fileParsed(fileName); - } - - m_currentFileName.clear(); - lexer = 0; - return true; -} - -void Driver::setupLexer(Lexer * lexer) -{ - // stl - lexer->addSkipWord("__STL_BEGIN_NAMESPACE"); - lexer->addSkipWord("__STL_END_NAMESPACE"); - lexer->addSkipWord("__STL_BEGIN_RELOPS_NAMESPACE"); - lexer->addSkipWord("__STL_END_RELOPS_NAMESPACE"); - lexer->addSkipWord("__STL_TEMPLATE_NULL"); - lexer->addSkipWord("__STL_TRY"); - lexer->addSkipWord("__STL_UNWIND"); - lexer->addSkipWord("__STL_NOTHROW"); - lexer->addSkipWord("__STL_NULL_TMPL_ARGS"); - lexer->addSkipWord("__STL_UNWIND", SkipWordAndArguments); - lexer->addSkipWord("__GC_CONST"); - lexer->addSkipWord("__HASH_ALLOC_INIT", SkipWordAndArguments); - lexer->addSkipWord("__STL_DEFAULT_ALLOCATOR", SkipWordAndArguments, "T"); - lexer->addSkipWord("__STL_MUTEX_INITIALIZER"); - lexer->addSkipWord("__STL_NULL_TMPL_ARGS"); - - // antlr - lexer->addSkipWord("ANTLR_BEGIN_NAMESPACE", SkipWordAndArguments); - lexer->addSkipWord("ANTLR_USE_NAMESPACE", SkipWordAndArguments); - lexer->addSkipWord("ANTLR_USING_NAMESPACE", SkipWordAndArguments); - lexer->addSkipWord("ANTLR_END_NAMESPACE"); - lexer->addSkipWord("ANTLR_C_USING", SkipWordAndArguments); - lexer->addSkipWord("ANTLR_API"); - - // gnu - lexer->addSkipWord("__extension__", SkipWordAndArguments); - lexer->addSkipWord("__attribute__", SkipWordAndArguments); - lexer->addSkipWord("__BEGIN_DECLS"); - lexer->addSkipWord("__END_DECLS"); - lexer->addSkipWord("__THROW"); - lexer->addSkipWord("__restrict"); - lexer->addSkipWord("__restrict__"); - lexer->addSkipWord("__attribute_pure__"); - lexer->addSkipWord("__attribute_malloc__"); - lexer->addSkipWord("__attribute_format_strfmon__"); - lexer->addSkipWord("__asm__", SkipWordAndArguments); - lexer->addSkipWord("__devinit"); - lexer->addSkipWord("__devinit__"); - lexer->addSkipWord("__init"); - lexer->addSkipWord("__init__"); - lexer->addSkipWord("__signed"); - lexer->addSkipWord("__signed__"); - lexer->addSkipWord("__unsigned"); - lexer->addSkipWord("__unsigned__"); - lexer->addSkipWord("asmlinkage"); - lexer->addSkipWord("____cacheline_aligned"); - lexer->addSkipWord("__glibcpp_class_requires", SkipWordAndArguments); - lexer->addSkipWord("__glibcpp_class2_requires", SkipWordAndArguments); - lexer->addSkipWord("__glibcpp_class4_requires", SkipWordAndArguments); - lexer->addSkipWord("__glibcpp_function_requires", SkipWordAndArguments); - lexer->addSkipWord("restrict"); - - lexer->addSkipWord("__BEGIN_NAMESPACE_STD"); - lexer->addSkipWord("__END_NAMESPACE_STD"); - lexer->addSkipWord("__BEGIN_NAMESPACE_C99"); - lexer->addSkipWord("__END_NAMESPACE_C99"); - lexer->addSkipWord("__USING_NAMESPACE_STD", SkipWordAndArguments); - - // kde - lexer->addSkipWord("K_SYCOCATYPE", SkipWordAndArguments); - lexer->addSkipWord("EXPORT_DOCKCLASS"); - lexer->addSkipWord("K_EXPORT_COMPONENT_FACTORY", SkipWordAndArguments); - lexer->addSkipWord("K_SYCOCAFACTORY", SkipWordAndArguments); - lexer->addSkipWord("KDE_DEPRECATED"); - - // qt - lexer->addSkipWord("Q_OVERRIDE", SkipWordAndArguments); - lexer->addSkipWord("Q_ENUMS", SkipWordAndArguments); - lexer->addSkipWord("Q_PROPERTY", SkipWordAndArguments); - lexer->addSkipWord("Q_CLASSINFO", SkipWordAndArguments); - lexer->addSkipWord("Q_SETS", SkipWordAndArguments); - lexer->addSkipWord("Q_UNUSED", SkipWordAndArguments); - lexer->addSkipWord("Q_CREATE_INSTANCE", SkipWordAndArguments); - lexer->addSkipWord("Q_DUMMY_COMPARISON_OPERATOR", SkipWordAndArguments); - lexer->addSkipWord("ACTIVATE_SIGNAL_WITH_PARAM", SkipWordAndArguments); - lexer->addSkipWord("Q_INLINE_TEMPLATES"); - lexer->addSkipWord("Q_TEMPLATE_EXTERN"); - lexer->addSkipWord("Q_TYPENAME"); - lexer->addSkipWord("Q_REFCOUNT"); - lexer->addSkipWord("Q_EXPLICIT"); - lexer->addSkipWord("QMAC_PASCAL"); - lexer->addSkipWord("QT_STATIC_CONST"); - lexer->addSkipWord("QT_STATIC_CONST_IMPL"); - lexer->addSkipWord("QT_WIN_PAINTER_MEMBERS"); - lexer->addSkipWord("QT_NC_MSGBOX"); - lexer->addSkipWord("Q_VARIANT_AS", SkipWordAndArguments); - lexer->addSkipWord("CALLBACK_CALL_TYPE"); - lexer->addSkipWord("Q_SLOTS"); - - // flex - lexer->addSkipWord("yyconst"); - lexer->addSkipWord("YY_RULE_SETUP"); - lexer->addSkipWord("YY_BREAK"); - lexer->addSkipWord("YY_RESTORE_YY_MORE_OFFSET"); - - // gtk - lexer->addSkipWord("G_BEGIN_DECLS"); - lexer->addSkipWord("G_END_DECLS"); - lexer->addSkipWord("G_GNUC_CONST"); - lexer->addSkipWord("G_CONST_RETURN"); - lexer->addSkipWord("GTKMAIN_C_VAR"); - lexer->addSkipWord("GTKVAR"); - lexer->addSkipWord("GDKVAR"); - lexer->addSkipWord("G_GNUC_PRINTF", SkipWordAndArguments); - - // windows - lexer->addSkipWord("WINAPI"); - lexer->addSkipWord("__stdcall"); - lexer->addSkipWord("__cdecl"); - lexer->addSkipWord("_cdecl"); - lexer->addSkipWord("CALLBACK"); - - // gcc extensions - addMacro(Macro("__asm__", "asm")); - addMacro(Macro("__inline", "inline")); - addMacro(Macro("__inline__", "inline")); - addMacro(Macro("__const", "const")); - addMacro(Macro("__const__", "const")); - addMacro(Macro("__volatile__", "volatile")); - addMacro(Macro("__complex__", "")); -} - -void Driver::setupParser(Parser * parser) -{ - Q_UNUSED(parser); -} - -void Driver::MacroManager::removeMacro(const QString& macroName) -{ - m_macros.erase(macroName); -} - -void Driver::addIncludePath(const QString &path) -{ - if(!path.trimmed().isEmpty()) - m_includePaths << path; -} - -QString Driver::findIncludeFile(const Dependence& dep) const -{ - QString fileName = dep.first; - - if(dep.second == Dep_Local){ - QString path = QFileInfo(currentFileName()).absolutePath(); - QFileInfo fileInfo(QFileInfo(path, fileName)); - if (fileInfo.exists() && fileInfo.isFile()) - return fileInfo.absoluteFilePath(); - - } - - QStringList::ConstIterator end(m_includePaths.end()); - for (QStringList::ConstIterator it(m_includePaths.begin()); it != end; ++it) { - QFileInfo fileInfo(*it, fileName); - if (fileInfo.exists() && fileInfo.isFile()) - return fileInfo.absoluteFilePath(); - } - - return QString(); -} - -void Driver::setResolveDependencesEnabled(bool enabled) -{ - depresolv = enabled; - if (depresolv) - setupPreProcessor(); -} - -void Driver::setupPreProcessor() -{ -} - -void Driver::fileParsed(const QString & fileName) -{ - Q_UNUSED(fileName); -} diff -Nru umbrello-4.12.3/umbrello/codeimport/kdevcppparser/driver.h umbrello-4.12.90/umbrello/codeimport/kdevcppparser/driver.h --- umbrello-4.12.3/umbrello/codeimport/kdevcppparser/driver.h 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/codeimport/kdevcppparser/driver.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,241 +0,0 @@ -/* This file is part of KDevelop - Copyright (C) 2002, 2003 Roberto Raggi - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef DRIVER_H -#define DRIVER_H - -#include "ast.h" -#include "position.h" - -#include -#include -#include -#include - -#include -#include - -class Lexer; -class Parser; - -class Problem -{ -public: - enum - { - Level_Error = 0, - Level_Warning, - Level_Todo, - Level_Fixme - }; - -public: - Problem() {} - Problem(const Problem& source) - : m_text(source.m_text), m_position(source.m_position), - m_level(source.m_level) {} - Problem(const QString& text, Position const& position, - int level = Level_Error) - : m_text(text), m_position(position), m_level(level) {} - - Problem& operator = (const Problem& source) - { - if (this != &source) { - m_text = source.m_text; - m_position = source.m_position; - m_level = source.m_level; - } - return(*this); - } - - bool operator == (const Problem& p) const - { - return ((m_text == p.m_text) && (m_position == p.m_position) - && (m_level == p.m_level)); - } - - QString text() const { return m_text; } - Position const& position() const { return m_position; } - int level() const { return m_level; } - -private: - QString m_text; - Position m_position; - int m_level; -}; - -enum - { - Dep_Global, - Dep_Local - }; - -typedef QPair Dependence; - -class Macro -{ -public: - typedef QString Argument; - typedef std::list ArgumentList; - - Macro() {} - explicit Macro(const QString &n) : m_name(n) {} - Macro(const QString &n, const QString &b) : m_name(n), m_body(b) {} - - Macro(const Macro& source) - : m_name(source.m_name), - m_fileName(source.m_fileName), - m_body(source.m_body), - m_arguments(source.m_arguments) {} - - Macro& operator = (const Macro& source) - { - m_name = source.m_name; - m_body = source.m_body; - m_fileName = source.m_fileName; - m_arguments = source.m_arguments; - return *this; - } - - bool operator == (const Macro& source) const - { - return - m_name == source.m_name && - m_fileName == source.m_fileName && - m_body == source.m_body && - m_arguments == source.m_arguments; - } - - QString const& name() const {return m_name;} - void setName(const QString& name) { m_name = name; } - - QString fileName() const { return m_fileName; } - void setFileName(const QString& fileName) { m_fileName = fileName; } - - QString body() const { return m_body; } - void setBody(const QString& body) { m_body = body; } - - bool hasArguments() const { return !m_arguments.empty();} - ArgumentList const& arguments() const {return m_arguments;} - - void clearArgumentList() {m_arguments.clear();} - void push_back(Argument const& argument) {m_arguments.push_back(argument);} - -private: - QString m_name; - QString m_fileName; - QString m_body; - ArgumentList m_arguments; -}; - -class SourceProvider -{ -public: - SourceProvider() {} - virtual ~SourceProvider() {} - - virtual QString contents(const QString& fileName) = 0; - virtual bool isModified(const QString& fileName) = 0; - -private: - SourceProvider(const SourceProvider& source); - void operator = (const SourceProvider& source); -}; - -class Driver -{ - typedef std::map MacroMap; -public: - Driver(); - virtual ~Driver(); - - SourceProvider* sourceProvider(); - void setSourceProvider(SourceProvider* sourceProvider); - - virtual void reset(); - - virtual bool parseFile(const QString& fileName, bool onlyPreProcesss=false, bool force=false); - virtual void fileParsed(const QString& fileName); - virtual void addDependence(const QString& fileName, const Dependence& dep); - virtual void addMacro(const Macro& macro) {m_macroManager.addMacro(macro);} - virtual void addProblem(const QString& fileName, const Problem& problem); - - QString currentFileName() const { return m_currentFileName; } - TranslationUnitAST::Node takeTranslationUnit(const QString& fileName); - TranslationUnitAST* translationUnit(const QString& fileName) const; - QMap dependences(const QString& fileName) const; -private: - MacroMap macros() const {return m_macroManager.macros();} -public: - QList problems(const QString& fileName) const; - bool hasMacro(const QString& name) const {return m_macroManager.hasMacro(name);} - Macro& macro(const QString& name) {return m_macroManager.macro(name);} - virtual void removeMacro(const QString& macroName) {m_macroManager.removeMacro(macroName);} - QStringList includePaths() const { return m_includePaths; } - virtual void addIncludePath(const QString &path); - - /// @todo remove - const QMap &parsedUnits() const { return m_parsedUnits; } - - virtual void setResolveDependencesEnabled(bool enabled); - bool isResolveDependencesEnabled() const { return depresolv; } - -protected: - virtual void setupLexer(Lexer* lexer); - virtual void setupParser(Parser* parser); - virtual void setupPreProcessor(); - -private: - QMap& findOrInsertDependenceList(const QString& fileName); - QList& findOrInsertProblemList(const QString& fileName); - QString findIncludeFile(const Dependence& dep) const; - -private: - - class MacroManager - { - public: - void addMacro(const Macro& macro); - bool hasMacro(const QString& name) const - {return (m_macros.find(name) != m_macros.end());} - Macro& macro(const QString& name) {return m_macros[ name];} - MacroMap const& macros() const; - void removeAllMacrosInFile(const QString& fileName); - void removeMacro(const QString& macroName); - void reset(); - private: - MacroMap m_macros; - }; - - QString m_currentFileName; - QMap< QString, QMap > m_dependences; - MacroManager m_macroManager; - QMap< QString, QList > m_problems; - QMap m_parsedUnits; - QStringList m_includePaths; - uint depresolv : 1; - Lexer *lexer; - SourceProvider* m_sourceProvider; - -private: - Driver(const Driver& source); - void operator = (const Driver& source); -}; - -#endif diff -Nru umbrello-4.12.3/umbrello/codeimport/kdevcppparser/errors.cpp umbrello-4.12.90/umbrello/codeimport/kdevcppparser/errors.cpp --- umbrello-4.12.3/umbrello/codeimport/kdevcppparser/errors.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/codeimport/kdevcppparser/errors.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ -/* This file is part of KDevelop - Copyright (C) 2002, 2003 Roberto Raggi - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "errors.h" -#include - -QT_STATIC_CONST_IMPL Error& Errors::InternalError = Error(1, -1, ki18n("Internal Error")); -QT_STATIC_CONST_IMPL Error& Errors::SyntaxError = Error(2, -1, ki18n("Syntax Error before '%1'")); -QT_STATIC_CONST_IMPL Error& Errors::ParseError = Error(3, -1, ki18n("Parse Error before '%1'")); diff -Nru umbrello-4.12.3/umbrello/codeimport/kdevcppparser/errors.h umbrello-4.12.90/umbrello/codeimport/kdevcppparser/errors.h --- umbrello-4.12.3/umbrello/codeimport/kdevcppparser/errors.h 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/codeimport/kdevcppparser/errors.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,42 +0,0 @@ -/* This file is part of KDevelop - Copyright (C) 2002, 2003 Roberto Raggi - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef ERRORS_H -#define ERRORS_H - -#include - -struct Error{ - int code; - int level; - KLocalizedString text; - - Error(int c, int l, const KLocalizedString& s) - : code(c), level(l), text(s) - {} -}; - -class Errors{ -public: - QT_STATIC_CONST Error& InternalError; - QT_STATIC_CONST Error& SyntaxError; - QT_STATIC_CONST Error& ParseError; -}; - -#endif diff -Nru umbrello-4.12.3/umbrello/codeimport/kdevcppparser/keywords.lut.h umbrello-4.12.90/umbrello/codeimport/kdevcppparser/keywords.lut.h --- umbrello-4.12.3/umbrello/codeimport/kdevcppparser/keywords.lut.h 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/codeimport/kdevcppparser/keywords.lut.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,123 +0,0 @@ -/* Automatically generated from keywords.table using /home/roberto/src/kdelibs/kjs/create_hash_table. DO NOT EDIT ! */ - - -static const struct HashEntry keywordEntries[] = { - { "template", Token_template, 0, 0, 0 }, - { "emit", Token_emit, 0, 0, &keywordEntries[88] }, - { "long", Token_long, 0, 0, 0 }, - { 0, 0, 0, 0, 0 }, - { "void", Token_void, 0, 0, &keywordEntries[113] }, - { 0, 0, 0, 0, 0 }, - { "explicit", Token_explicit, 0, 0, &keywordEntries[100] }, - { "enum", Token_enum, 0, 0, &keywordEntries[105] }, - { 0, 0, 0, 0, 0 }, - { "continue", Token_continue, 0, 0, &keywordEntries[99] }, - { "k_dcop_signals", Token_k_dcop_signals, 0, 0, &keywordEntries[104] }, - { "auto", Token_auto, 0, 0, &keywordEntries[91] }, - { 0, 0, 0, 0, 0 }, - { "Q_OBJECT", Token_Q_OBJECT, 0, 0, &keywordEntries[86] }, - { "and_eq", Token_and_eq, 0, 0, 0 }, - { 0, 0, 0, 0, 0 }, - { "operator", Token_operator, 0, 0, 0 }, - { 0, 0, 0, 0, 0 }, - { "class", Token_class, 0, 0, &keywordEntries[90] }, - { 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0 }, - { "while", Token_while, 0, 0, 0 }, - { "k_dcop", Token_k_dcop, 0, 0, 0 }, - { "compl", Token_compl, 0, 0, 0 }, - { "bitand", Token_bitand, 0, 0, &keywordEntries[97] }, - { "__int64", Token_int, 0, 0, &keywordEntries[89] }, - { 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0 }, - { "bitor", Token_bitor, 0, 0, 0 }, - { 0, 0, 0, 0, 0 }, - { "friend", Token_friend, 0, 0, 0 }, - { 0, 0, 0, 0, 0 }, - { "signed", Token_signed, 0, 0, 0 }, - { "double", Token_double, 0, 0, 0 }, - { "K_DCOP", Token_K_DCOP, 0, 0, &keywordEntries[111] }, - { "const", Token_const, 0, 0, &keywordEntries[92] }, - { 0, 0, 0, 0, 0 }, - { "inline", Token_inline, 0, 0, &keywordEntries[98] }, - { 0, 0, 0, 0, 0 }, - { "do", Token_do, 0, 0, 0 }, - { 0, 0, 0, 0, 0 }, - { "const_cast", Token_const_cast, 0, 0, 0 }, - { 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0 }, - { "not_eq", Token_not_eq, 0, 0, &keywordEntries[102] }, - { 0, 0, 0, 0, 0 }, - { "static", Token_static, 0, 0, 0 }, - { 0, 0, 0, 0, 0 }, - { "throw", Token_throw, 0, 0, 0 }, - { "slots", Token_slots, 0, 0, &keywordEntries[87] }, - { 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0 }, - { "static_cast", Token_static_cast, 0, 0, &keywordEntries[115] }, - { "default", Token_default, 0, 0, &keywordEntries[95] }, - { "sizeof", Token_sizeof, 0, 0, 0 }, - { 0, 0, 0, 0, 0 }, - { "switch", Token_switch, 0, 0, 0 }, - { 0, 0, 0, 0, 0 }, - { "mutable", Token_mutable, 0, 0, 0 }, - { "dynamic_cast", Token_dynamic_cast, 0, 0, 0 }, - { "extern", Token_extern, 0, 0, 0 }, - { 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0 }, - { "asm", Token_asm, 0, 0, 0 }, - { 0, 0, 0, 0, 0 }, - { "signals", Token_signals, 0, 0, &keywordEntries[106] }, - { 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0 }, - { "case", Token_case, 0, 0, 0 }, - { "for", Token_for, 0, 0, 0 }, - { "char", Token_char, 0, 0, &keywordEntries[101] }, - { 0, 0, 0, 0, 0 }, - { "export", Token_export, 0, 0, &keywordEntries[94] }, - { "int", Token_int, 0, 0, 0 }, - { 0, 0, 0, 0, 0 }, - { "private", Token_private, 0, 0, &keywordEntries[103] }, - { 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0 }, - { "not", Token_not, 0, 0, 0 }, - { 0, 0, 0, 0, 0 }, - { "else", Token_else, 0, 0, &keywordEntries[93] }, - { 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0 }, - { "bool", Token_bool, 0, 0, 0 }, - { "catch", Token_catch, 0, 0, 0 }, - { "__asm__", Token_asm, 0, 0, 0 }, - { "and", Token_and, 0, 0, 0 }, - { "break", Token_break, 0, 0, &keywordEntries[110] }, - { "delete", Token_delete, 0, 0, 0 }, - { "float", Token_float, 0, 0, &keywordEntries[96] }, - { "goto", Token_goto, 0, 0, 0 }, - { "if", Token_if, 0, 0, 0 }, - { "namespace", Token_namespace, 0, 0, 0 }, - { "new", Token_new, 0, 0, 0 }, - { "or", Token_or, 0, 0, &keywordEntries[107] }, - { "or_eq", Token_or_eq, 0, 0, 0 }, - { "protected", Token_protected, 0, 0, 0 }, - { "public", Token_public, 0, 0, &keywordEntries[109] }, - { "register", Token_register, 0, 0, 0 }, - { "reinterpret_cast", Token_reinterpret_cast, 0, 0, 0 }, - { "return", Token_return, 0, 0, 0 }, - { "short", Token_short, 0, 0, 0 }, - { "struct", Token_struct, 0, 0, 0 }, - { "this", Token_this, 0, 0, 0 }, - { "try", Token_try, 0, 0, &keywordEntries[108] }, - { "typedef", Token_typedef, 0, 0, 0 }, - { "typeid", Token_typeid, 0, 0, 0 }, - { "typename", Token_typename, 0, 0, 0 }, - { "union", Token_union, 0, 0, 0 }, - { "unsigned", Token_unsigned, 0, 0, &keywordEntries[112] }, - { "using", Token_using, 0, 0, 0 }, - { "virtual", Token_virtual, 0, 0, &keywordEntries[114] }, - { "volatile", Token_volatile, 0, 0, 0 }, - { "xor", Token_xor, 0, 0, 0 }, - { "xor_eq", Token_xor_eq, 0, 0, 0 } -}; - -static const struct HashTable keyword = { 2, 116, keywordEntries, 86 }; diff -Nru umbrello-4.12.3/umbrello/codeimport/kdevcppparser/lexer.cpp umbrello-4.12.90/umbrello/codeimport/kdevcppparser/lexer.cpp --- umbrello-4.12.3/umbrello/codeimport/kdevcppparser/lexer.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/codeimport/kdevcppparser/lexer.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,451 +0,0 @@ -/* This file is part of KDevelop - Copyright (C) 2002, 2003 Roberto Raggi - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "lexer.h" - -#include "debug_utils.h" -#include "lookup.h" -#include "keywords.lut.h" - -#include - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "assignFunctor.hpp" - -namespace boost { - namespace spirit { - namespace classic { - namespace impl { - bool isalnum_(QChar const& c) { return isalnum_(c.toAscii()); } - bool isalpha_(QChar const& c) { return isalpha_(c.toAscii()); } - bool isblank_(QChar const& c) { return isblank_(c.toAscii()); } - bool isdigit_(QChar const& c) { return isdigit_(c.toAscii()); } - bool isxdigit_(QChar const& c) { return isxdigit_(c.toAscii()); } - } - } - } -} - -template -struct tilde : public std::unary_function<_Tp, _Tp> { - _Tp operator()(_Tp& __x) const { - return ~__x; - } -}; - -using namespace boost::spirit::classic; -using phoenix::arg1; -using phoenix::arg2; -using phoenix::arg3; -using phoenix::construct_; -using phoenix::function; -using phoenix::var; - -SkipRule Lexer::m_SkipRule = nothing_p; - -#if defined(KDEVELOP_BGPARSER) -#include - -class KDevTread: public QThread -{ -public: - static void yield() { msleep(0); } -}; - -inline void qthread_yield() -{ - KDevTread::yield(); -} - -#endif - -/** Utility closure that defines a result value. - Used to return values from grammars (copied from cpp lexer in spirit - repository). */ -template < typename ResultT > -struct result_closure : closure, ResultT> { - typedef closure, ResultT> base_t; - typename base_t::member1 result_; -}; - -/** Stuff to construct a QString from iterators */ -struct constructQString_impl { - template - struct result { - typedef QString type; - }; - - template - QString operator()(_Arg1 const& first, _Arg2 const& last) { - return QString(&*first, &*last - &*first); - } -}; - -const function constructQString = - constructQString_impl(); - -struct identifier : - grammar::context_t> { - template < typename ScannerT > - struct definition { - typedef rule rule_t; - rule_t main; - - rule_t const& start() const { - return main; - } - - definition(identifier const& self) { - main = (lexeme_d[ - ((alpha_p | '_') >> *(alnum_p | '_')) - [self.result_ = constructQString(arg1, arg2)] - ]); - } - }; -} identifier_g; - -struct operator_ : - grammar::context_t> { - template < typename ScannerT > - struct definition { - typedef rule::context_t> rule_t; - rule_t main; - - rule_t const& start() const { - return main; - } - - definition(operator_ const& self) { - main = - (str_p("::")[ main.result_ = Token_scope] - | (str_p("->*") | ".*")[ main.result_ = Token_ptrmem] - | (str_p("<<=") | ">>=" | "+=" | "-=" | "*=" | "/=" | "%=" | "^=" | "&=" | "|=")[ main.result_ = Token_assign] - | str_p("<<")[ main.result_ = Token_left_shift] - | (str_p("==") | "!=")[ main.result_ = Token_eq] - | str_p("<=")[ main.result_ = Token_leq] - | str_p(">=")[ main.result_ = Token_geq] - | str_p("&&")[ main.result_ = Token_and] - | str_p("||")[ main.result_ = Token_or] - | str_p("++")[ main.result_ = Token_incr] - | str_p("--")[ main.result_ = Token_decr] - | str_p("->")[ main.result_ = Token_arrow] - | str_p("##")[ main.result_ = Token_concat] - | str_p("...")[ main.result_ = Token_ellipsis] - ) - [ self.result_ = construct_(main.result_, arg1, arg2)]; - } - }; -} operator_g; - -struct charLiteral : - grammar::context_t> { - template < typename ScannerT > - struct definition { - typedef rule::context_t> rule_t; - rule_t main; - - rule_t const& start() const { - return main; - } - - definition(charLiteral const& self) { - main = - (!ch_p('L') >> ch_p('\'') - >> *((anychar_p - '\'' - '\\') | gr_escapeSequence) - >> '\'') - [ self.result_ = construct_(Token_char_literal, arg1, arg2)]; - } - }; -} charLiteral_g; - -struct numberLiteral : - grammar::context_t> { - template < typename ScannerT > - struct definition { - typedef rule::context_t> rule_t; - rule_t main; - - rule_t const& start() const { - return main; - } - - definition(numberLiteral const& self) { - main = - (ch_p('0') >> ch_p('x') >> + xdigit_p | + digit_p) - [ self.result_ = construct_(Token_number_literal, arg1, arg2)]; - } - }; -} numberLiteral_g; - -typedef std::pair Dependency; - -struct DependencyClosure - : boost::spirit::classic::closure { - member1 m_word; - member2 m_scope; -}; - -Lexer::CharRule gr_stringLiteral = - ch_p('"') >> *((anychar_p - '"' - '\\') | gr_escapeSequence) >> '"'; -Lexer::CharRule gr_whiteSpace = blank_p | (ch_p('\\') >> eol_p); -Lexer::CharRule gr_lineComment = (str_p("//") >> (*(anychar_p - eol_p))); -Lexer::CharRule gr_multiLineComment = confix_p("/*", *anychar_p, "*/"); -Lexer::CharRule gr_skipTillEol = - *(gr_whiteSpace | gr_lineComment | gr_multiLineComment | charLiteral_g - | gr_stringLiteral | (anychar_p - '\\' - eol_p) | (ch_p('\\') >> eol_p)); - -Token::Token() - : m_type(-1), - m_start(), - m_end(), - m_text() -{ -} - -Token::Token(int type, CharIterator start, CharIterator end) - : m_type(type), - m_start(start.get_position()), - m_end(end.get_position()), - m_text(&*start, &*end - &*start) -{ -} - -Token& Token::operator=(Token const & p) -{ - if (this != &p) { - m_type = p.m_type; - m_start = p.m_start; - m_end = p.m_end; - m_text = p.m_text; - } - return *this; -} - -QDebug operator<<(QDebug out, const Token &t) -{ - out << "Token(" - << "type:" << t.type() - << "text:" << t.text() - << "start:" << t.getStartPosition() - << "end:" << t.getEndPosition() - << ")"; - return out; -} - -Token Lexer::Source::createToken(int type, CharIterator start, - CharIterator end) const -{ - return Token(type, start, end); -} - -using namespace std; - -struct LexerData { - typedef QMap Scope; - typedef QList StaticChain; - - StaticChain staticChain; - - void beginScope() { - Scope scope; - staticChain.push_front(scope); - } - - void endScope() { - staticChain.pop_front(); - } - - void bind(const QString& name, const QString& value) { - Q_ASSERT(staticChain.size() > 0); - staticChain.front().insert(name, value); - } - - bool hasBind(const QString& name) const { - StaticChain::ConstIterator it = staticChain.begin(); - while (it != staticChain.end()) { - const Scope& scope = *it; - ++it; - - if (scope.contains(name)) - return true; - } - - return false; - } - - QString apply(const QString& name) const { - StaticChain::ConstIterator it = staticChain.begin(); - while (it != staticChain.end()) { - const Scope& scope = *it; - ++it; - - if (scope.contains(name)) - return scope[ name ]; - } - - return QString(); - } - -}; - -Lexer::Lexer(Driver* driver) - : m_driver(driver), - m_recordComments(false), - m_preprocessLexer(m_driver) -{ - reset(); -} - -Lexer::~Lexer() -{ -} - -bool Lexer::setSource(const QString& source, - const QString& p_filename) -{ - reset(); - m_preprocessLexer.setSource(source, p_filename); - m_source.set_filename(p_filename); - return tokenize(); - -} - -void Lexer::reset() -{ - m_tokens.clear(); - m_source.reset(); -} - -Position const& Lexer::getTokenPosition(const Token& token) const -{ - return token.getStartPosition(); -} - -void Lexer::nextToken(Token& tk) -{ - m_source.parse(*gr_whiteSpace); - - Position startPosition(currentPosition()); - - QChar ch = m_source.currentChar(); - if (ch.isNull() || ch.isSpace()) { - /* skip */ - } else if (m_source.get_startLine() - && m_source.parse(ch_p('#') >> *gr_whiteSpace).hit) { - m_source.set_startLine(false); - - QString directive; - m_source.parse(identifier_g[ assign(directive)]); // read the directive - - handleDirective(directive); - } else if (m_source.parse - ( - if_p(var(m_recordComments)) - [ gr_lineComment | gr_multiLineComment - [var(tk) = construct_(Token_comment, arg1, arg2)] - ] - .else_p[ gr_lineComment | gr_multiLineComment] - | charLiteral_g[assign(tk)] - | - gr_stringLiteral - [var(tk) = construct_(Token_string_literal, arg1, arg2)] - ).hit) { - } else if (ch.isLetter() || ch == '_') { - CharIterator start = m_source.get_ptr(); - QString ide; - m_source.parse(identifier_g[assign(ide)]); - int k = Lookup::find(&keyword, ide); - if (k != -1) { - tk = m_source.createToken(k, start); - } else { - tk = m_source.createToken(Token_identifier, start); - } - } else if (m_source.parse(numberLiteral_g[assign(tk)] - | operator_g[ assign(tk)] - ).hit) { - } else { - CharIterator l_ptr = m_source.get_ptr(); - m_source.nextChar(); - tk = m_source.createToken(ch.unicode(), l_ptr); - } - if (m_source.parse(eol_p).hit) - m_source.set_startLine(true); - else - m_source.set_startLine(false); -} - -bool Lexer::tokenize() -{ - if (!m_preprocessLexer.preprocess()) - return false; -#if 0 - QByteArray l_tmp = m_preprocessLexer.preprocessedString().toAscii(); - for (int i = 0; i < l_tmp.size(); ++i) - std::cout << l_tmp.at(i); - std::cout << std::endl; -#endif - m_source.set_source(m_preprocessLexer.preprocessedString()); - m_source.set_startLine(true); - for (;;) { - Token tk; - nextToken(tk); - - if (tk.type() != -1) - m_tokens.push_back(tk); - - if (m_source.currentChar().isNull()) - break; - } - - Token tk = m_source.createToken(Token_eof, m_source.get_ptr()); - m_tokens.push_back(tk); - return true; -} - -void Lexer::handleDirective(const QString& directive) -{ - Q_UNUSED(directive); - assert(directive != "define"); - assert(directive != "else"); - assert(directive != "elif"); - assert(directive != "endif"); - assert(directive != "if"); - assert(directive != "ifdef"); - assert(directive != "ifndef"); - assert(directive != "include"); - assert(directive != "undef"); - assert(0); - // skip line - m_source.parse(gr_skipTillEol); -} - -// *IMPORTANT* -// please, don't include lexer.moc here, because Lexer isn't a QObject class!! -// if you have problem while recompiling try to remove cppsupport/.deps, -// cppsupport/Makefile.in and rerun automake/autoconf - diff -Nru umbrello-4.12.3/umbrello/codeimport/kdevcppparser/lexer.h umbrello-4.12.90/umbrello/codeimport/kdevcppparser/lexer.h --- umbrello-4.12.3/umbrello/codeimport/kdevcppparser/lexer.h 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/codeimport/kdevcppparser/lexer.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,169 +0,0 @@ -/* This file is part of KDevelop - Copyright (C) 2002, 2003 Roberto Raggi - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef LEXER_H -#define LEXER_H - -#include "preprocesslexer.h" -/* -#include - - -namespace boost { namespace spirit { namespace classic { namespace impl { - bool isalnum_(QChar const& c); - bool isalpha_(QChar const& c); - bool isblank_(QChar const& c); - bool isdigit_(QChar const& c); -}}}} -*/ - -#include "driver.h" -#include "position.h" - -#include -#include -#include -#include -#include - -#include "skip_rule.hpp" - -using boost::spirit::classic::parse_info; -using boost::spirit::classic::rule; -using boost::spirit::classic::scanner; -using boost::spirit::classic::ext::skip_rule_parser; - -typedef rule > SkipRule; -typedef skip_rule_parser CharParser; -typedef scanner CharScanner; -typedef CharParser::skip_scanner_policies_t CharPolicies; - -struct LexerData; - -class Lexer -{ - typedef std::list TokenList; -public: - typedef rule > CharRule; - typedef TokenList::const_iterator TokenIterator; - - explicit Lexer(Driver* driver); - ~Lexer(); - - void addSkipWord(const QString& word, SkipType skipType = SkipWord, - const QString& str = QString()) - { m_preprocessLexer.addSkipWord(word, skipType, str); } - - bool setSource(const QString& source, const QString& p_filename); - void setRecordComments(bool record); - Position currentPosition() const { return m_source.get_currentPosition(); } - - Token const& lookAhead(TokenIterator p_it, int n) const { - std::advance(p_it, n); - assert(p_it != m_tokens.end()); - return *p_it; - } - Position const& getTokenPosition(const Token& token) const; - TokenIterator tokenBegin() const {return m_tokens.begin();} -private: - bool tokenize(); - void nextToken(Token& token); - bool recordComments() const; - void reset(); - void handleDirective(const QString& directive); -private: - static SkipRule m_SkipRule; - - Driver* m_driver; - TokenList m_tokens; - - class Source - { - public: - Source() {} - - Token createToken(int type, CharIterator start, CharIterator end) const; - Token createToken(int type, CharIterator start) const { - return createToken(type, start, m_ptr); - } - QChar currentChar() const { - return m_ptr != m_endPtr ? *m_ptr : QChar::Null; - } - bool eof() const {return m_ptr == m_endPtr;} - int length() const {return std::distance(m_ptr, m_endPtr);} - void nextChar() { - QChar l_current = *m_ptr++; - switch(l_current.toAscii()) { - case '\n': - case '\r': - m_startLine = true; - break; - } - } - - template - parse_info parse(_RuleT const& p_rule) { - parse_info l_return = - CharParser::parse(m_ptr, m_endPtr, p_rule, m_SkipRule); - if (l_return.hit) - m_ptr = l_return.stop; - return l_return; - } - - void reset() { - m_ptr = CharIterator(); - m_startLine = true; - } - - void set_filename(const QString& p_filename) { m_filename = p_filename; } - void set_source(QString const& source) { - m_ptr = CharIterator(source.data(), - source.data() + source.length(), - Position(m_filename)); - } - // getters - Position get_currentPosition() const {return m_ptr.get_position();} - CharIterator get_ptr() const {return m_ptr;} - bool get_startLine() const {return m_startLine;} - // setters - void set_startLine(bool p) {m_startLine = p;} - private: - QString m_filename; - CharIterator m_ptr; - const CharIterator m_endPtr; - bool m_startLine; - }; - - Source m_source; - bool m_recordComments; - PreprocessLexer m_preprocessLexer; -}; - -inline bool Lexer::recordComments() const -{ - return m_recordComments; -} - -inline void Lexer::setRecordComments(bool record) -{ - m_preprocessLexer.setRecordComments(record); - m_recordComments = record; -} - -#endif diff -Nru umbrello-4.12.3/umbrello/codeimport/kdevcppparser/lookup.cpp umbrello-4.12.90/umbrello/codeimport/kdevcppparser/lookup.cpp --- umbrello-4.12.3/umbrello/codeimport/kdevcppparser/lookup.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/codeimport/kdevcppparser/lookup.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,111 +0,0 @@ -// -*- c-basic-offset: 2 -*- -/* - * This file is part of the KDE libraries - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -// adapted to kdevelop by Roberto Raggi - -#include "lookup.h" - -#include "debug_utils.h" - -const HashEntry* Lookup::findEntry(const struct HashTable *table, - const QChar *c, unsigned int len) -{ - if (table->type != 2) { - uDebug() << "KJS: Unknown hash table version"; - return 0; - } - char *ascii = new char[len+1]; - unsigned int i; - for (i = 0; i < len; ++i, ++c) { - if (!c->row()) - ascii[i] = c->cell(); - else - break; - } - ascii[i] = '\0'; - - int h = hash(ascii) % table->hashSize; - const HashEntry *e = &table->entries[h]; - - // empty bucket ? - if (!e->s) { - delete [] ascii; - return 0; - } - - do { - // compare strings - if (strcmp(ascii, e->s) == 0) { - delete [] ascii; - return e; - } - // try next bucket - e = e->next; - } while (e); - - delete [] ascii; - return 0; -} - -const HashEntry* Lookup::findEntry(const struct HashTable *table, - const QString &s) -{ - return findEntry(table, s.unicode(), s.length()); -} - -int Lookup::find(const struct HashTable *table, - const QChar *c, unsigned int len) -{ - const HashEntry *entry = findEntry(table, c, len); - if (entry) - return entry->value; - return -1; -} - -int Lookup::find(const struct HashTable *table, const QString &s) -{ - return find(table, s.unicode(), s.length()); -} - -unsigned int Lookup::hash(const QChar *c, unsigned int len) -{ - unsigned int val = 0; - // ignoring rower byte - for (unsigned int i = 0; i < len; ++i, ++c) { - val += c->cell(); - } - - return val; -} - -unsigned int Lookup::hash(const QString &key) -{ - return hash(key.unicode(), key.length()); -} - -unsigned int Lookup::hash(const char *s) -{ - unsigned int val = 0; - while (*s) - val += *s++; - - return val; -} diff -Nru umbrello-4.12.3/umbrello/codeimport/kdevcppparser/lookup.h umbrello-4.12.90/umbrello/codeimport/kdevcppparser/lookup.h --- umbrello-4.12.3/umbrello/codeimport/kdevcppparser/lookup.h 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/codeimport/kdevcppparser/lookup.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,118 +0,0 @@ -// -*- c-basic-offset: 2 -*- -/* - * This file is part of the KDE libraries - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -// adapted to kdevelop by Roberto Raggi - -#ifndef KJSLOOKUP_H -#define KJSLOOKUP_H - -#include - - /** - * An entry in a hash table. - */ - struct HashEntry { - /** - * s is the key (e.g. a property name) - */ - const char *s; - /** - * value is the result value (usually an enum value) - */ - int value; - /** - * attr is a set for flags (e.g. the property flags, see object.h) - */ - short int attr; - /** - * params is another number. For property hashtables, it is used to - * denote the number of argument of the function - */ - short int params; - /** - * next is the pointer to the next entry for the same hash value - */ - const HashEntry *next; - }; - - /** - * A hash table - * Usually the hashtable is generated by the create_hash_table script, from a .table file. - * - * The implementation uses an array of entries, "size" is the total size of that array. - * The entries between 0 and hashSize-1 are the entry points - * for each hash value, and the entries between hashSize and size-1 - * are the overflow entries for the hash values that need one. - * The "next" pointer of the entry links entry points to overflow entries, - * and links overflow entries between them. - */ - struct HashTable { - /** - * type is a version number. Currently always 2 - */ - int type; - /** - * size is the total number of entries in the hashtable, including the null entries, - * i.e. the size of the "entries" array. - * Used to iterate over all entries in the table - */ - int size; - /** - * pointer to the array of entries - * Mind that some entries in the array are null (0, 0, 0, 0). - */ - const HashEntry *entries; - /** - * the maximum value for the hash. Always smaller than size. - */ - int hashSize; - }; - - /** - * @short Fast keyword lookup. - */ - class Lookup { - public: - /** - * Find an entry in the table, and return its value (i.e. the value field of HashEntry) - */ - static int find(const struct HashTable *table, const QString& s); - static int find(const struct HashTable *table, const QChar *c, unsigned int len); - - /** - * Find an entry in the table, and return the entry - * This variant gives access to the other attributes of the entry, - * especially the attr field. - */ - static const HashEntry* findEntry(const struct HashTable *table, - const QString &s); - static const HashEntry* findEntry(const struct HashTable *table, - const QChar *c, unsigned int len); - - /** - * Calculate the hash value for a given key - */ - static unsigned int hash(const QString &key); - static unsigned int hash(const QChar *c, unsigned int len); - static unsigned int hash(const char *s); - }; - -#endif diff -Nru umbrello-4.12.3/umbrello/codeimport/kdevcppparser/parser.cpp umbrello-4.12.90/umbrello/codeimport/kdevcppparser/parser.cpp --- umbrello-4.12.3/umbrello/codeimport/kdevcppparser/parser.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/codeimport/kdevcppparser/parser.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,4280 +0,0 @@ -/* This file is part of KDevelop - Copyright (C) 2002, 2003 Roberto Raggi - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -// c++ support -#include "parser.h" -#include "driver.h" -#include "lexer.h" -#include "errors.h" -#include "debug_utils.h" - -// kde support -#include - -// qt support -#include -#include - -bool Parser::advance(int tk, char const* descr) -{ - const Token& token = (*m_tokenIt); - if (token != tk) { - reportError(i18n("'%1' expected found '%2'", QString(descr), - token.text())); - return false; - } - ++m_tokenIt; - return true; -} - -bool Parser::check(int tk) -{ - const Token& token = (*m_tokenIt); - if (token != tk) { - return false; - } - ++m_tokenIt; - return true; -} - -//@todo remove me -enum { - OBJC_CLASS, - OBJC_PROTOCOL, - OBJC_ALIAS -}; - -struct ParserPrivateData { - ParserPrivateData() {} -}; - -Parser::Parser(Driver* driver, Lexer* lexer) - : m_driver(driver), - lex(lexer) -{ - d = new ParserPrivateData(); - m_maxProblems = 5; - objcp = false; -} - -Parser::~Parser() -{ - delete d; - d = 0; -} - -bool Parser::reportError(const Error& err) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::reportError()"; - if (m_problems < m_maxProblems) { - ++m_problems; - const Token& token = (*m_tokenIt); - Position position = lex->getTokenPosition(token); - - QString s = (*m_tokenIt).text(); - s = s.left(30).trimmed(); - if (s.isEmpty()) - s = i18n(""); - - m_driver->addProblem(m_driver->currentFileName(), Problem(err.text.subs(s).toString(), position)); - } - - return true; -} - -bool Parser::reportError(const QString& msg) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::reportError()"; - if (m_problems < m_maxProblems) { - ++m_problems; - const Token& token = (*m_tokenIt); - Position position = lex->getTokenPosition(token); - - m_driver->addProblem(m_driver->currentFileName(), Problem(msg, position)); - } - - return true; -} - -void Parser::syntaxError() -{ - (void) reportError(Errors::SyntaxError); -} - -bool Parser::skipUntil(int token) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::skipUntil()"; - while (!(*m_tokenIt).isNull()) { - if ((*m_tokenIt) == token) - return true; - - ++m_tokenIt; - } - - return false; -} - -bool Parser::skipUntilDeclaration() -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::skipUntilDeclaration()"; - - while (!(*m_tokenIt).isNull()) { - - switch ((*m_tokenIt)) { - case ';': - case '~': - case Token_scope: - case Token_identifier: - case Token_operator: - case Token_char: - case Token_wchar_t: - case Token_bool: - case Token_short: - case Token_int: - case Token_long: - case Token_signed: - case Token_unsigned: - case Token_float: - case Token_double: - case Token_void: - case Token_extern: - case Token_namespace: - case Token_using: - case Token_typedef: - case Token_asm: - case Token_template: - case Token_export: - - case Token_const: // cv - case Token_volatile: // cv - - case Token_public: - case Token_protected: - case Token_private: - case Token_signals: // Qt - case Token_slots: // Qt - return true; - - case '}': - return false; - - default: - ++m_tokenIt; - } - } - - return false; -} - -bool Parser::skipUntilStatement() -{ - //uDebug()<< "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::skipUntilStatement() -- token = " << (*m_tokenIt).text(); - - while (!(*m_tokenIt).isNull()) { - switch ((*m_tokenIt)) { - case ';': - case '{': - case '}': - case Token_const: - case Token_volatile: - case Token_identifier: - case Token_case: - case Token_default: - case Token_if: - case Token_switch: - case Token_while: - case Token_do: - case Token_for: - case Token_break: - case Token_continue: - case Token_return: - case Token_goto: - case Token_try: - case Token_catch: - case Token_throw: - case Token_char: - case Token_wchar_t: - case Token_bool: - case Token_short: - case Token_int: - case Token_long: - case Token_signed: - case Token_unsigned: - case Token_float: - case Token_double: - case Token_void: - case Token_class: - case Token_struct: - case Token_union: - case Token_enum: - case Token_scope: - case Token_template: - case Token_using: - return true; - - default: - ++m_tokenIt; - } - } - - return false; -} - -bool Parser::skip(int l, int r) -{ - int count = 0; - while (!(*m_tokenIt).isNull()) { - int tk = (*m_tokenIt); - - if (tk == l) - ++count; - else if (tk == r) - --count; - else if (l != '{' && (tk == '{' || tk == '}' || tk == ';')) - return false; - - if (count == 0) - return true; - - ++m_tokenIt; - } - - return false; -} - -bool Parser::skipCommaExpression(AST::Node& node) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::skipCommaExpression()"; - - TokenIterator start = m_tokenIt; - - AST::Node expr; - if (!skipExpression(expr)) - return false; - - QString comment; - while ((*m_tokenIt) == ',') { - comment.clear(); - advanceAndCheckTrailingComment(comment); - - if (!skipExpression(expr)) { - reportError(i18n("expression expected")); - return false; - } - } - - AST::Node ast = CreateNode(); - update_pos(ast, start, m_tokenIt); - node = ast; - - return true; -} - -bool Parser::skipExpression(AST::Node& node) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::skipExpression()"; - - TokenIterator start = m_tokenIt; - - while (!(*m_tokenIt).isNull()) { - int tk = (*m_tokenIt); - - switch (tk) { - case '(': - skip('(', ')'); - ++m_tokenIt; - break; - - case '[': - skip('[', ']'); - ++m_tokenIt; - break; - -#if 0 - case Token_identifier: - ++m_tokenIt; - if ((*m_tokenIt) == Token_identifier) - return true; - break; -#endif - - case ';': - case ',': - case ']': - case ')': - case '{': - case '}': - case Token_case: - case Token_default: - case Token_if: - case Token_while: - case Token_do: - case Token_for: - case Token_break: - case Token_continue: - case Token_return: - case Token_goto: { - AST::Node ast = CreateNode(); - update_pos(ast, start, m_tokenIt); - node = ast; - } - return true; - - default: - ++m_tokenIt; - } - } - - return false; -} - -bool Parser::parseName(NameAST::Node& node) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseName()"; - - GroupAST::Node winDeclSpec; - parseWinDeclSpec(winDeclSpec); - - TokenIterator start = m_tokenIt; - - NameAST::Node ast = CreateNode(); - - if ((*m_tokenIt) == Token_scope) { - ast->setGlobal(true); - ++m_tokenIt; - } - - TokenIterator idx = m_tokenIt; - - while (true) { - ClassOrNamespaceNameAST::Node n; - if (!parseUnqualifiedName(n)) { - return false; - } - - if ((*m_tokenIt) == Token_scope) { - ++m_tokenIt; - ast->addClassOrNamespaceName(n); - if ((*m_tokenIt) == Token_template) - ++m_tokenIt; /// skip optional template #### @todo CHECK - } else { - ast->setUnqualifiedName(n); - break; - } - } - - if (idx == m_tokenIt) - return false; - - update_pos(ast, start, m_tokenIt); - node = ast; - - return true; -} - -bool Parser::parseTranslationUnit(TranslationUnitAST::Node& node) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseTranslationUnit()"; - - TokenIterator start = m_tokenIt = lex->tokenBegin(); - - m_problems = 0; - TranslationUnitAST::Node tun = CreateNode(); - node = tun; - while (!(*m_tokenIt).isNull()) { - DeclarationAST::Node def; - TokenIterator startDecl = m_tokenIt; - if (!parseDeclaration(def)) { - // error recovery - if (startDecl == m_tokenIt) - ++m_tokenIt; // skip at least one token - skipUntilDeclaration(); - } - node->addDeclaration(def); - } - - update_pos(node, start, m_tokenIt); - - // force (0, 0) as start position - node->setStartPosition(Position()); - - return m_problems == 0; -} - -bool Parser::parseDeclaration(DeclarationAST::Node& node) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseDeclaration()"; - - // catch first comment - Position ps = m_tokenIt->getStartPosition(); - if (ps.line == 1 && ps.column == 1 && (*m_tokenIt) == Token_comment) - { - FileAST::Node ast = CreateNode(); - ast->setFileName(m_driver->currentFileName()); - QString comment = (*m_tokenIt).text(); - - if ((*m_tokenIt) == Token_comment) { - ast->setComment(comment); - ++m_tokenIt; - } - //uDebug() << m_driver->currentFileName() << comment; - node = ast; - return true; - } - - QString comment; - while ((*m_tokenIt) == Token_comment) { - comment += (*m_tokenIt).text(); - ++m_tokenIt; - } - - if ((*m_tokenIt).isNull()) { - // FIXME: add fetched comment to FileAST - return false; - } - - TokenIterator start = m_tokenIt; - bool success = false; - - switch ((*m_tokenIt)) { - - case ';': - ++m_tokenIt; - return true; - - case Token_extern: - success = parseLinkageSpecification(node); - break; - - case Token_namespace: - success = parseNamespace(node); - break; - - case Token_using: - success = parseUsing(node); - break; - - case Token_typedef: - success = parseTypedef(node); - break; - - case Token_asm: - success = parseAsmDefinition(node); - break; - - case Token_template: - case Token_export: - success = parseTemplateDeclaration(node); - break; - - default: { - // m_tokenIt = start; - - if (objcp && parseObjcDef(node)) - return true; - - m_tokenIt = start; - - GroupAST::Node storageSpec; - parseStorageClassSpecifier(storageSpec); - - GroupAST::Node cv; - parseCvQualify(cv); - - TypeSpecifierAST::Node spec; - AST::Node declarator; - if (parseEnumSpecifier(spec) || parseClassSpecifier(spec)) { - spec->setCvQualify(cv); - - GroupAST::Node cv2; - parseCvQualify(cv2); - spec->setCv2Qualify(cv2); - - InitDeclaratorListAST::Node declarators; - parseInitDeclaratorList(declarators); - - if (!advance(';', ";")) - return false; - - if (!comment.isEmpty()) { - //uDebug() << "Parser::parseDeclaration(spec): comment is " << comment; - spec->setComment(comment); - } - - SimpleDeclarationAST::Node ast = CreateNode(); - ast->setStorageSpecifier(storageSpec); - ast->setTypeSpec(spec); - ast->setInitDeclaratorList(declarators); - update_pos(ast, start, m_tokenIt); - node = ast; - - return true; - } - - m_tokenIt = start; - success = parseDeclarationInternal(node, comment); - } - - } // end switch - - if (success && !comment.isEmpty()) { - //uDebug() << "Parser::parseDeclaration(): comment is " << comment; - node->setComment(comment); - } - return success; -} - -bool Parser::parseLinkageSpecification(DeclarationAST::Node& node) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseLinkageSpecification()"; - - TokenIterator start = m_tokenIt; - - if ((*m_tokenIt) != Token_extern) { - return false; - } - ++m_tokenIt; - - LinkageSpecificationAST::Node ast = CreateNode(); - - TokenIterator startExternType = m_tokenIt; - if ((*m_tokenIt) == Token_string_literal) { - ++m_tokenIt; - AST::Node externType = CreateNode(); - update_pos(externType, startExternType, m_tokenIt); - - ast->setExternType(externType); - } - - if ((*m_tokenIt) == '{') { - LinkageBodyAST::Node linkageBody; - parseLinkageBody(linkageBody); - ast->setLinkageBody(linkageBody); - } else { - DeclarationAST::Node decl; - if (!parseDeclaration(decl)) { - reportError(i18n("Declaration syntax error")); - } - ast->setDeclaration(decl); - } - - update_pos(ast, start, m_tokenIt); - - node = ast; - - return true; -} - -bool Parser::parseLinkageBody(LinkageBodyAST::Node& node) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseLinkageBody()"; - - TokenIterator start = m_tokenIt; - - if ((*m_tokenIt) != '{') { - return false; - } - ++m_tokenIt; - - LinkageBodyAST::Node lba = CreateNode(); - node = lba; - - while (!(*m_tokenIt).isNull()) { - int tk = (*m_tokenIt); - - if (tk == '}') - break; - - DeclarationAST::Node def; - TokenIterator startDecl = m_tokenIt; - if (parseDeclaration(def)) { - node->addDeclaration(def); - } else { - // error recovery - if (startDecl == m_tokenIt) - ++m_tokenIt; // skip at least one token - skipUntilDeclaration(); - } - } - - if ((*m_tokenIt) != '}') { - reportError(i18n("} expected")); - } else - ++m_tokenIt; - - update_pos(node, start, m_tokenIt); - return true; -} - -bool Parser::parseNamespace(DeclarationAST::Node& node) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseNamespace()"; - - TokenIterator start = m_tokenIt; - - if ((*m_tokenIt) != Token_namespace) { - return false; - } - ++m_tokenIt; - - TokenIterator startNamespaceName = m_tokenIt; - if ((*m_tokenIt) == Token_identifier) { - ++m_tokenIt; - } - AST::Node namespaceName = CreateNode(); - update_pos(namespaceName, startNamespaceName, m_tokenIt); - - if ((*m_tokenIt) == '=') { - // namespace alias - ++m_tokenIt; - - NameAST::Node name; - if (parseName(name)) { - if (!advance(';', ";")) - return false; - - NamespaceAliasAST::Node ast = CreateNode(); - ast->setNamespaceName(namespaceName); - ast->setAliasName(name); - update_pos(ast, start, m_tokenIt); - node = ast; - return true; - } else { - reportError(i18n("namespace expected")); - return false; - } - } else if ((*m_tokenIt) != '{') { - reportError(i18n("{ expected")); - return false; - } - - NamespaceAST::Node ast = CreateNode(); - ast->setNamespaceName(namespaceName); - - LinkageBodyAST::Node linkageBody; - parseLinkageBody(linkageBody); - - ast->setLinkageBody(linkageBody); - update_pos(ast, start, m_tokenIt); - node = ast; - - return true; -} - -bool Parser::parseUsing(DeclarationAST::Node& node) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseUsing()"; - - TokenIterator start = m_tokenIt; - - if ((*m_tokenIt) != Token_using) { - return false; - } - ++m_tokenIt; - - if ((*m_tokenIt) == Token_namespace) { - if (!parseUsingDirective(node)) { - return false; - } - update_pos(node, start, m_tokenIt); - return true; - } - - UsingAST::Node ast = CreateNode(); - - TokenIterator startTypeName = m_tokenIt; - if ((*m_tokenIt) == Token_typename) { - ++m_tokenIt; - AST::Node tn = CreateNode(); - update_pos(tn, startTypeName, m_tokenIt); - ast->setTypeName(tn); - } - - NameAST::Node name; - if (!parseName(name)) - return false; - - ast->setName(name); - - if (!advance(';', ";")) - return false; - - update_pos(ast, start, m_tokenIt); - node = ast; - - return true; -} - -bool Parser::parseUsingDirective(DeclarationAST::Node& node) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseUsingDirective()"; - - TokenIterator start = m_tokenIt; - - if ((*m_tokenIt) != Token_namespace) { - return false; - } - ++m_tokenIt; - - NameAST::Node name; - if (!parseName(name)) { - reportError(i18n("Namespace name expected")); - return false; - } - - if (!advance(';', ";")) - return false; - - UsingDirectiveAST::Node ast = CreateNode(); - ast->setName(name); - update_pos(ast, start, m_tokenIt); - node = ast; - - return true; -} - -bool Parser::parseOperatorFunctionId(AST::Node& node) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseOperatorFunctionId()"; - - TokenIterator start = m_tokenIt; - - if ((*m_tokenIt) != Token_operator) { - return false; - } - ++m_tokenIt; - - AST::Node op; - if (parseOperator(op)) { - AST::Node asn = CreateNode(); - node = asn; - update_pos(node, start, m_tokenIt); - return true; - } else { - // parse cast operator - GroupAST::Node cv; - parseCvQualify(cv); - - TypeSpecifierAST::Node spec; - if (!parseSimpleTypeSpecifier(spec)) { - syntaxError(); - return false; - } - spec->setCvQualify(cv); - - GroupAST::Node cv2; - parseCvQualify(cv2); - spec->setCv2Qualify(cv2); - - AST::Node ptrOp; - while (parsePtrOperator(ptrOp)) - ; - - AST::Node asn = CreateNode(); - node = asn; - update_pos(node, start, m_tokenIt); - return true; - } -} - -bool Parser::parseTemplateArgumentList(TemplateArgumentListAST::Node& node, bool reportError) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseTemplateArgumentList()"; - - TokenIterator start = m_tokenIt; - - TemplateArgumentListAST::Node ast = CreateNode(); - - AST::Node templArg; - if (!parseTemplateArgument(templArg)) - return false; - ast->addArgument(templArg); - - QString comment; - while ((*m_tokenIt) == ',') { - comment.clear(); - advanceAndCheckTrailingComment(comment); - - if (!parseTemplateArgument(templArg)) { - if (reportError) { - syntaxError(); - break; - } else - return false; - } - if (!comment.isEmpty()) - templArg->setComment(comment); - ast->addArgument(templArg); - } - - update_pos(ast, start, m_tokenIt); - node = ast; - - return true; -} - -bool Parser::parseTypedef(DeclarationAST::Node& node) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseTypedef()"; - - TokenIterator start = m_tokenIt; - - if ((*m_tokenIt) != Token_typedef) { - return false; - } - ++m_tokenIt; - - TypeSpecifierAST::Node spec; - if (!parseTypeSpecifierOrClassSpec(spec)) { - reportError(i18n("Need a type specifier to declare")); - return false; - } - - InitDeclaratorListAST::Node declarators; - if (!parseInitDeclaratorList(declarators)) { - //reportError(i18n("Need an identifier to declare")); - //return false; - } - - if (!advance(';', ";")) - return false; - - TypedefAST::Node ast = CreateNode(); - ast->setTypeSpec(spec); - ast->setInitDeclaratorList(declarators); - update_pos(ast, start, m_tokenIt); - node = ast; - - return true; -} - -bool Parser::parseAsmDefinition(DeclarationAST::Node& /*node*/) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseAsmDefinition()"; - - if (!advance(Token_asm, "asm")) - return false; - - GroupAST::Node cv; - parseCvQualify(cv); - - skip('(', ')'); - if (!advance(')', ")")) - return false; - if (!advance(';', ";")) - return false; - - return true; -} - -bool Parser::parseTemplateDeclaration(DeclarationAST::Node& node) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseTemplateDeclaration()"; - - TokenIterator start = m_tokenIt; - - AST::Node exp; - - TokenIterator startExport = m_tokenIt; - if ((*m_tokenIt) == Token_export) { - ++m_tokenIt; - AST::Node n = CreateNode(); - update_pos(n, startExport, m_tokenIt); - exp = n; - } - - if ((*m_tokenIt) != Token_template) { - return false; - } - ++m_tokenIt; - - TemplateParameterListAST::Node params; - if ((*m_tokenIt) == '<') { - ++m_tokenIt; - if ((*m_tokenIt) != '>') - parseTemplateParameterList(params); - - if (!advance('>', ">")) - return false; - } - - DeclarationAST::Node def; - if (!parseDeclaration(def)) { - reportError(i18n("expected a declaration")); - } - - TemplateDeclarationAST::Node ast = CreateNode(); - ast->setExported(exp); - ast->setTemplateParameterList(params); - ast->setDeclaration(def); - update_pos(ast, start, m_tokenIt); - node = ast; - - return true; -} - -bool Parser::parseOperator(AST::Node& /*node*/) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseOperator()"; - QString text = (*m_tokenIt).text(); - - switch ((*m_tokenIt)) { - case Token_new: - case Token_delete: - ++m_tokenIt; - if ((*m_tokenIt) == '[' && lex->lookAhead(m_tokenIt, 1) == ']') { - ++m_tokenIt; - ++m_tokenIt; - text += "[]"; - } - return true; - - case '+': - case '-': - case '*': - case '/': - case '%': - case '^': - case '&': - case '|': - case '~': - case '!': - case '=': - case '<': - case '>': - case ',': - case Token_assign: - case Token_left_shift: - case Token_eq: - case Token_not_eq: - case Token_leq: - case Token_geq: - case Token_and: - case Token_or: - case Token_incr: - case Token_decr: - case Token_ptrmem: - case Token_arrow: - ++m_tokenIt; - return true; - - default: - if ((*m_tokenIt) == '(' && lex->lookAhead(m_tokenIt, 1) == ')') { - ++m_tokenIt; - ++m_tokenIt; - return true; - } else if ((*m_tokenIt) == '[' && lex->lookAhead(m_tokenIt, 1) == ']') { - ++m_tokenIt; - ++m_tokenIt; - return true; - } - } - - return false; -} - -bool Parser::parseCvQualify(GroupAST::Node& node) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseCvQualify()"; - - TokenIterator start = m_tokenIt; - - GroupAST::Node ast = CreateNode(); - - int n = 0; - while (!(*m_tokenIt).isNull()) { - int tk = (*m_tokenIt); - if (tk == Token_const || tk == Token_volatile) { - ++n; - TokenIterator startWord = m_tokenIt; - ++m_tokenIt; - AST::Node word = CreateNode(); - update_pos(word, startWord, m_tokenIt); - ast->addNode(word); - } else - break; - } - - if (n == 0) - return false; - - - //uDebug() << "-----------------> token = " << (*m_tokenIt).text(); - update_pos(ast, start, m_tokenIt); - - node = ast; - return true; -} - -bool Parser::parseSimpleTypeSpecifier(TypeSpecifierAST::Node& node) -{ - TokenIterator start = m_tokenIt; - bool isIntegral = false; - bool done = false; - - while (!done) { - - switch ((*m_tokenIt)) { - case Token_char: - case Token_wchar_t: - case Token_bool: - case Token_short: - case Token_int: - case Token_long: - case Token_signed: - case Token_unsigned: - case Token_float: - case Token_double: - case Token_void: - isIntegral = true; - ++m_tokenIt; - break; - - default: - done = true; - } - } - - TypeSpecifierAST::Node ast = CreateNode(); - if (isIntegral) { - ClassOrNamespaceNameAST::Node cl = CreateNode(); - - AST::Node n = CreateNode(); - update_pos(n, start, m_tokenIt); - cl->setName(n); - update_pos(cl, start, m_tokenIt); - - NameAST::Node name = CreateNode(); - name->setUnqualifiedName(cl); - update_pos(name, start, m_tokenIt); - ast->setName(name); - - } else { - NameAST::Node name; - if (!parseName(name)) { - m_tokenIt = start; - return false; - } - ast->setName(name); - } - - update_pos(ast, start, m_tokenIt); - node = ast; - return true; -} - -bool Parser::parsePtrOperator(AST::Node& node) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parsePtrOperator()"; - - TokenIterator start = m_tokenIt; - - if ((*m_tokenIt) == '&') { - ++m_tokenIt; - } else if ((*m_tokenIt) == '*') { - ++m_tokenIt; - } else { - TokenIterator index = m_tokenIt; - AST::Node memPtr; - if (!parsePtrToMember(memPtr)) { - m_tokenIt = index; - return false; - } - } - - GroupAST::Node cv; - parseCvQualify(cv); - - AST::Node ast = CreateNode(); - update_pos(ast, start, m_tokenIt); - node = ast; - - return true; -} - -bool Parser::parseTemplateArgument(AST::Node& node) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseTemplateArgument()"; - - TokenIterator start = m_tokenIt; - if (parseTypeId(node)) { - if ((*m_tokenIt) == ',' || (*m_tokenIt) == '>') - return true; - } - - m_tokenIt = start; - if (!parseLogicalOrExpression(node, true)) { - return false; - } - - return true; -} - -bool Parser::parseTypeSpecifier(TypeSpecifierAST::Node& spec) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseTypeSpecifier()"; - - GroupAST::Node cv; - parseCvQualify(cv); - - if (parseElaboratedTypeSpecifier(spec) || parseSimpleTypeSpecifier(spec)) { - spec->setCvQualify(cv); - - GroupAST::Node cv2; - parseCvQualify(cv2); - spec->setCv2Qualify(cv2); - - return true; - } - - return false; -} - -bool Parser::parseDeclarator(DeclaratorAST::Node& node) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseDeclarator()"; - - TokenIterator start = m_tokenIt; - - DeclaratorAST::Node ast = CreateNode(); - - DeclaratorAST::Node decl; - NameAST::Node declId; - - AST::Node ptrOp; - while (parsePtrOperator(ptrOp)) { - ast->addPtrOp(ptrOp); - } - - if ((*m_tokenIt) == '(') { - ++m_tokenIt; - - if (!parseDeclarator(decl)) { - return false; - } - ast->setSubDeclarator(decl); - - if ((*m_tokenIt) != ')') { - return false; - } - ++m_tokenIt; - } else { - - if ((*m_tokenIt) == ':') { - // unnamed bitfield - } else if (parseDeclaratorId(declId)) { - ast->setDeclaratorId(declId); - } else { - m_tokenIt = start; - return false; - } - - if ((*m_tokenIt) == ':') { - ++m_tokenIt; - AST::Node expr; - if (!parseConstantExpression(expr)) { - reportError(i18n("Constant expression expected")); - } - goto update_pos; - } - } - - { - bool isVector = true; - - while ((*m_tokenIt) == '[') { - TokenIterator startArray = m_tokenIt; - ++m_tokenIt; - AST::Node expr; - parseCommaExpression(expr); - - if (!advance(']', "]")) - return false; - AST::Node array = CreateNode(); - update_pos(array, startArray, m_tokenIt); - ast->addArrayDimension(array); - isVector = true; - } - - bool skipParen = false; - if ((*m_tokenIt) == Token_identifier && lex->lookAhead(m_tokenIt, 1) == '(' && lex->lookAhead(m_tokenIt, 2) == '(') { - ++m_tokenIt; - ++m_tokenIt; - skipParen = true; - } - - if (ast->subDeclarator() && (!isVector || (*m_tokenIt) != '(')) { - m_tokenIt = start; - return false; - } - - TokenIterator index = m_tokenIt; - if ((*m_tokenIt) == '(') { - ++m_tokenIt; - - ParameterDeclarationClauseAST::Node params; - if (!parseParameterDeclarationClause(params)) { - //uDebug() << "----------------------> not a parameter declaration, maybe an initializer!?"; - m_tokenIt = index; - goto update_pos; - } - ast->setParameterDeclarationClause(params); - - if ((*m_tokenIt) != ')') { - m_tokenIt = index; - goto update_pos; - } - - ++m_tokenIt; // skip ')' - - TokenIterator startConstant = m_tokenIt; - if ((*m_tokenIt) == Token_const) { - ++m_tokenIt; - AST::Node constant = CreateNode(); - update_pos(constant, startConstant, m_tokenIt); - ast->setConstant(constant); - } - - GroupAST::Node except; - if (parseExceptionSpecification(except)) { - ast->setExceptionSpecification(except); - } - } - - if (skipParen) { - if ((*m_tokenIt) != ')') { - reportError(i18n("')' expected")); - } else - ++m_tokenIt; - } - } - -update_pos: - update_pos(ast, start, m_tokenIt); - node = ast; - - return true; -} - -bool Parser::parseAbstractDeclarator(DeclaratorAST::Node& node) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseDeclarator()"; - TokenIterator start = m_tokenIt; - - DeclaratorAST::Node ast = CreateNode(); - - DeclaratorAST::Node decl; - NameAST::Node declId; - - AST::Node ptrOp; - while (parsePtrOperator(ptrOp)) { - ast->addPtrOp(ptrOp); - } - - if ((*m_tokenIt) == '(') { - ++m_tokenIt; - - if (!parseAbstractDeclarator(decl)) { - return false; - } - ast->setSubDeclarator(decl); - - if ((*m_tokenIt) != ')') { - return false; - } - ++m_tokenIt; - } - - { - while ((*m_tokenIt) == '[') { - TokenIterator startArray = m_tokenIt; - ++m_tokenIt; - AST::Node expr; - skipCommaExpression(expr); - - if (!advance(']', "]")) - return false; - AST::Node array = CreateNode(); - update_pos(array, startArray, m_tokenIt); - ast->addArrayDimension(array); - } - - bool skipParen = false; - if ((*m_tokenIt) == Token_identifier && lex->lookAhead(m_tokenIt, 1) == '(' && lex->lookAhead(m_tokenIt, 2) == '(') { - ++m_tokenIt; - ++m_tokenIt; - skipParen = true; - } - - TokenIterator index = m_tokenIt; - if ((*m_tokenIt) == '(') { - ++m_tokenIt; - - ParameterDeclarationClauseAST::Node params; - if (!parseParameterDeclarationClause(params)) { - m_tokenIt = index; - goto update_pos; - } - ast->setParameterDeclarationClause(params); - - if ((*m_tokenIt) != ')') { - m_tokenIt = index; - goto update_pos; - } else - ++m_tokenIt; - - TokenIterator startConstant = m_tokenIt; - if ((*m_tokenIt) == Token_const) { - ++m_tokenIt; - AST::Node constant = CreateNode(); - update_pos(constant, startConstant, m_tokenIt); - ast->setConstant(constant); - } - - GroupAST::Node except; - if (parseExceptionSpecification(except)) { - ast->setExceptionSpecification(except); - } - } - - if (skipParen) { - if ((*m_tokenIt) != ')') { - reportError(i18n("')' expected")); - } else - ++m_tokenIt; - } - - } - -update_pos: - update_pos(ast, start, m_tokenIt); - node = ast; - - return true; -} - -bool Parser::parseEnumSpecifier(TypeSpecifierAST::Node& node) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseEnumSpecifier()"; - - QString comment; - while ((*m_tokenIt) == Token_comment) { - comment += (*m_tokenIt).text(); - ++m_tokenIt; - } - if ((*m_tokenIt).isNull()) - return false; - - TokenIterator start = m_tokenIt; - - if ((*m_tokenIt) != Token_enum) { - return false; - } - - ++m_tokenIt; - - NameAST::Node name; - parseName(name); - - if ((*m_tokenIt) != '{') { - m_tokenIt = start; - return false; - } - ++m_tokenIt; - - EnumSpecifierAST::Node ast = CreateNode(); - ast->setName(name); - - EnumeratorAST::Node enumerator; - if (parseEnumerator(enumerator)) { - ast->addEnumerator(enumerator); - - QString comment; - while ((*m_tokenIt) == ',') { - comment = ""; - advanceAndCheckTrailingComment(comment); - if (!comment.isEmpty()) { - EnumeratorAST *lastLit = ast->enumeratorList().last(); - if (lastLit) - lastLit->setComment(comment); - } - - if (!parseEnumerator(enumerator)) { - //reportError(i18n("Enumerator expected")); - break; - } - - ast->addEnumerator(enumerator); - } - } - - if ((*m_tokenIt) == Token_comment) - ++m_tokenIt; - if ((*m_tokenIt) != '}') - reportError(i18n("} missing")); - else - ++m_tokenIt; - - update_pos(ast, start, m_tokenIt); - node = ast; - - return true; -} - -bool Parser::parseTemplateParameterList(TemplateParameterListAST::Node& node) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseTemplateParameterList()"; - - TokenIterator start = m_tokenIt; - - TemplateParameterListAST::Node ast = CreateNode(); - - TemplateParameterAST::Node param; - if (!parseTemplateParameter(param)) { - return false; - } - ast->addTemplateParameter(param); - - QString comment; - while ((*m_tokenIt) == ',') { - comment.clear(); - advanceAndCheckTrailingComment(comment); - - if (!parseTemplateParameter(param)) { - syntaxError(); - break; - } else { - if (!comment.isEmpty()) - param->setComment(comment); - ast->addTemplateParameter(param); - } - } - - update_pos(ast, start, m_tokenIt); - node = ast; - - return true; -} - -bool Parser::parseTemplateParameter(TemplateParameterAST::Node& node) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseTemplateParameter()"; - - TokenIterator start = m_tokenIt; - TemplateParameterAST::Node ast = CreateNode(); - - TypeParameterAST::Node typeParameter; - ParameterDeclarationAST::Node param; - - int tk = (*m_tokenIt); - - if ((tk == Token_class || tk == Token_typename || tk == Token_template) && parseTypeParameter(typeParameter)) { - ast->setTypeParameter(typeParameter); - goto ok; - } - - if (!parseParameterDeclaration(param)) - return false; - ast->setTypeValueParameter(param); - -ok: - update_pos(ast, start, m_tokenIt); - node = ast; - - return true; -} - -bool Parser::parseTypeParameter(TypeParameterAST::Node& node) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseTypeParameter()"; - - TokenIterator start = m_tokenIt; - TypeParameterAST::Node ast = CreateNode(); - - AST::Node kind = ast_from_token(m_tokenIt); - ast->setKind(kind); - - switch ((*m_tokenIt)) { - - case Token_class: - case Token_typename: { - ++m_tokenIt; // skip class - - // parse optional name - NameAST::Node name; - if (parseName(name)) { - ast->setName(name); - if ((*m_tokenIt) == '=') { - ++m_tokenIt; - - AST::Node typeId; - if (!parseTypeId(typeId)) { - syntaxError(); - return false; - } - ast->setTypeId(typeId); - } - } - } - break; - - case Token_template: { - ++m_tokenIt; // skip template - if (!advance('<', "<")) - return false; - - TemplateParameterListAST::Node params; - if (!parseTemplateParameterList(params)) { - return false; - } - ast->setTemplateParameterList(params); - - if (!advance('>', ">")) - return false; - - if ((*m_tokenIt) == Token_class) - ++m_tokenIt; - - // parse optional name - NameAST::Node name; - if (parseName(name)) { - ast->setName(name); - if ((*m_tokenIt) == '=') { - ++m_tokenIt; - - AST::Node typeId; - if (!parseTypeId(typeId)) { - syntaxError(); - return false; - } - ast->setTypeId(typeId); - } - } - - if ((*m_tokenIt) == '=') { - ++m_tokenIt; - - NameAST::Node templ_name; - parseName(templ_name); - } - } - break; - - default: - return false; - - } // end switch - - - update_pos(ast, start, m_tokenIt); - node = ast; - return true; -} - -bool Parser::parseStorageClassSpecifier(GroupAST::Node& node) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseStorageClassSpecifier()"; - - TokenIterator start = m_tokenIt; - GroupAST::Node ast = CreateNode(); - - while (!(*m_tokenIt).isNull()) { - int tk = (*m_tokenIt); - if (tk == Token_friend || tk == Token_auto || tk == Token_register || tk == Token_static || - tk == Token_extern || tk == Token_mutable) { - TokenIterator startNode = m_tokenIt; - ++m_tokenIt; - - AST::Node n = CreateNode(); - update_pos(n, startNode, m_tokenIt); - ast->addNode(n); - } else - break; - } - - if (ast->nodeList().count() == 0) - return false; - - update_pos(ast, start, m_tokenIt); - node = ast; - return true; -} - -bool Parser::parseFunctionSpecifier(GroupAST::Node& node) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseFunctionSpecifier()"; - - TokenIterator start = m_tokenIt; - GroupAST::Node ast = CreateNode(); - - while (!(*m_tokenIt).isNull()) { - int tk = (*m_tokenIt); - if (tk == Token_inline || tk == Token_virtual || tk == Token_explicit) { - TokenIterator startNode = m_tokenIt; - ++m_tokenIt; - - AST::Node n = CreateNode(); - update_pos(n, startNode, m_tokenIt); - ast->addNode(n); - } else { - break; - } - } - - if (ast->nodeList().count() == 0) - return false; - - update_pos(ast, start, m_tokenIt); - node = ast; - return true; -} - -bool Parser::parseTypeId(AST::Node& node) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseTypeId()"; - - /// @todo implement the AST for typeId - TokenIterator start = m_tokenIt; - AST::Node ast = CreateNode(); - - TypeSpecifierAST::Node spec; - if (!parseTypeSpecifier(spec)) { - return false; - } - - DeclaratorAST::Node decl; - parseAbstractDeclarator(decl); - - update_pos(ast, start, m_tokenIt); - node = ast; - - return true; -} - -bool Parser::parseInitDeclaratorList(InitDeclaratorListAST::Node& node) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseInitDeclaratorList()"; - - TokenIterator start = m_tokenIt; - - InitDeclaratorListAST::Node ast = CreateNode(); - InitDeclaratorAST::Node decl; - - if (!parseInitDeclarator(decl)) { - return false; - } - ast->addInitDeclarator(decl); - - QString comment; - while ((*m_tokenIt) == ',') { - comment = ""; - advanceAndCheckTrailingComment(comment); - - if (!parseInitDeclarator(decl)) { - syntaxError(); - break; - } - if (!comment.isEmpty()) - decl->setComment(comment); - ast->addInitDeclarator(decl); - } - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseInitDeclaratorList() -- end"; - - update_pos(ast, start, m_tokenIt); - node = ast; - - return true; -} - -bool Parser::parseParameterDeclarationClause(ParameterDeclarationClauseAST::Node& node) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseParameterDeclarationClause()"; - - TokenIterator start = m_tokenIt; - - ParameterDeclarationClauseAST::Node ast = CreateNode(); - - ParameterDeclarationListAST::Node params; - if (!parseParameterDeclarationList(params)) { - - if ((*m_tokenIt) == ')') - goto good; - - if ((*m_tokenIt) == Token_ellipsis && lex->lookAhead(m_tokenIt, 1) == ')') { - AST::Node ellipsis = ast_from_token(m_tokenIt); - ast->setEllipsis(ellipsis); - ++m_tokenIt; - goto good; - } - return false; - } - - if ((*m_tokenIt) == Token_ellipsis) { - AST::Node ellipsis = ast_from_token(m_tokenIt); - ast->setEllipsis(ellipsis); - ++m_tokenIt; - } - -good: - ast->setParameterDeclarationList(params); - - /// @todo add ellipsis - update_pos(ast, start, m_tokenIt); - node = ast; - - return true; -} - -bool Parser::parseParameterDeclarationList(ParameterDeclarationListAST::Node& node) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseParameterDeclarationList()"; - - TokenIterator start = m_tokenIt; - - ParameterDeclarationListAST::Node ast = CreateNode(); - - ParameterDeclarationAST::Node param; - if (!parseParameterDeclaration(param)) { - m_tokenIt = start; - return false; - } - ast->addParameter(param); - - QString comment; - while ((*m_tokenIt) == ',') { - comment.clear(); - advanceAndCheckTrailingComment(comment); - - if ((*m_tokenIt) == Token_ellipsis) - break; - - if (!parseParameterDeclaration(param)) { - m_tokenIt = start; - return false; - } - if (!comment.isEmpty()) - param->setComment(comment); - ast->addParameter(param); - } - - update_pos(ast, start, m_tokenIt); - node = ast; - - return true; -} - -bool Parser::parseParameterDeclaration(ParameterDeclarationAST::Node& node) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseParameterDeclaration()"; - - TokenIterator start = m_tokenIt; - - // parse decl spec - TypeSpecifierAST::Node spec; - if (!parseTypeSpecifier(spec)) { - m_tokenIt = start; - return false; - } - - TokenIterator index = m_tokenIt; - - DeclaratorAST::Node decl; - if (!parseDeclarator(decl)) { - m_tokenIt = index; - - // try with abstract declarator - if (!parseAbstractDeclarator(decl)) - return false; - } - - AST::Node expr; - if ((*m_tokenIt) == '=') { - ++m_tokenIt; - if (!parseLogicalOrExpression(expr, true)) { - //reportError(i18n("Expression expected")); - } - } - - ParameterDeclarationAST::Node ast = CreateNode(); - ast->setTypeSpec(spec); - ast->setDeclarator(decl); - ast->setExpression(expr); - - update_pos(ast, start, m_tokenIt); - node = ast; - - return true; -} - -bool Parser::parseClassSpecifier(TypeSpecifierAST::Node& node) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseClassSpecifier()"; - - TokenIterator start = m_tokenIt; - - AST::Node classKey; - TokenIterator classKeyStart = m_tokenIt; - - int kind = (*m_tokenIt); - if (kind == Token_class || kind == Token_struct || kind == Token_union) { - AST::Node asn = CreateNode(); - classKey = asn; - ++m_tokenIt; - update_pos(classKey, classKeyStart, m_tokenIt); - } else { - return false; - } - - GroupAST::Node winDeclSpec; - parseWinDeclSpec(winDeclSpec); - - while ((*m_tokenIt) == Token_identifier && lex->lookAhead(m_tokenIt, 1) == Token_identifier) - ++m_tokenIt; - - NameAST::Node name; - parseName(name); - - BaseClauseAST::Node bases; - if ((*m_tokenIt) == ':') { - if (!parseBaseClause(bases)) { - skipUntil('{'); - } - } - - QString comment; - while ((*m_tokenIt) == Token_comment) { - comment += (*m_tokenIt).text(); - ++m_tokenIt; - } - if ((*m_tokenIt) != '{') { - m_tokenIt = start; - return false; - } - - if (!advance('{', "{")) - return false; - - ClassSpecifierAST::Node ast = CreateNode(); - ast->setWinDeclSpec(winDeclSpec); - ast->setClassKey(classKey); - ast->setName(name); - ast->setBaseClause(bases); - - while (!(*m_tokenIt).isNull()) { - if ((*m_tokenIt) == '}') - break; - - DeclarationAST::Node memSpec = CreateNode(); - TokenIterator startDecl = m_tokenIt; - if (!parseMemberSpecification(memSpec)) { - if (startDecl == m_tokenIt) - ++m_tokenIt; // skip at least one token - skipUntilDeclaration(); - } else - ast->addDeclaration(memSpec); - } - - if ((*m_tokenIt) != '}') { - reportError(i18n("} missing")); - } else - ++m_tokenIt; - - update_pos(ast, start, m_tokenIt); - node = ast; - - return true; -} - -bool Parser::parseAccessSpecifier(AST::Node& node) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseAccessSpecifier()"; - - TokenIterator start = m_tokenIt; - - switch ((*m_tokenIt)) { - case Token_public: - case Token_protected: - case Token_private: { - AST::Node asn = CreateNode(); - node = asn; - ++m_tokenIt; - update_pos(node, start, m_tokenIt); - return true; - } - } - - return false; -} - -void Parser::advanceAndCheckTrailingComment(QString& comment) -{ - Token t = *m_tokenIt; - int previousTokenEndLine = t.getEndPosition().line; - ++m_tokenIt; - if ((*m_tokenIt) != Token_comment) - return; - t = *m_tokenIt; - int commentStartLine = t.getStartPosition().line; - if (commentStartLine != previousTokenEndLine) - return; - comment += (*m_tokenIt).text(); - ++m_tokenIt; -} - -void Parser::advance_nr(int tk, char const* descr) -{ - const Token& token = (*m_tokenIt); - if (token != tk) { - reportError(i18n("'%1' expected found '%2'", QString(descr), - token.text())); - } else - ++m_tokenIt; -} - -AST::Node Parser::ast_from_token(TokenIterator tk) const -{ - AST::Node node = CreateNode(); - TokenIterator l_tmp = tk; - ++l_tmp; - update_pos(node, tk, l_tmp); - return node; -} - -bool Parser::parseMemberSpecification(DeclarationAST::Node& node) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseMemberSpecification()"; - - QString comment; - while ((*m_tokenIt) == Token_comment) { - comment += (*m_tokenIt).text(); - ++m_tokenIt; - } - if ((*m_tokenIt).isNull()) - return false; - - TokenIterator start = m_tokenIt; - - AST::Node access; - - if ((*m_tokenIt) == ';') { - advanceAndCheckTrailingComment(comment); - if (!comment.isEmpty()) - node->setComment(comment); - return true; - } else if ((*m_tokenIt) == Token_Q_OBJECT || (*m_tokenIt) == Token_K_DCOP) { - ++m_tokenIt; - return true; - } else if ((*m_tokenIt) == Token_signals || (*m_tokenIt) == Token_k_dcop || (*m_tokenIt) == Token_k_dcop_signals) { - AccessDeclarationAST::Node ast = CreateNode(); - ++m_tokenIt; - AST::Node n = CreateNode(); - update_pos(n, start, m_tokenIt); - ast->addAccess(n); - if (!advance(':', ":")) - return false; - update_pos(ast, start, m_tokenIt); - node = ast; - return true; - } else if (parseTypedef(node)) { - return true; - } else if (parseUsing(node)) { - return true; - } else if (parseTemplateDeclaration(node)) { - return true; - } else if (parseAccessSpecifier(access)) { - AccessDeclarationAST::Node ast = CreateNode(); - ast->addAccess(access); - - TokenIterator startSlot = m_tokenIt; - if ((*m_tokenIt) == Token_slots) { - ++m_tokenIt; - AST::Node sl = CreateNode(); - update_pos(sl, startSlot, m_tokenIt); - ast->addAccess(sl); - } - if (!advance(':', ":")) - return false; - update_pos(ast, start, m_tokenIt); - node = ast; - return true; - } - - m_tokenIt = start; - - GroupAST::Node storageSpec; - parseStorageClassSpecifier(storageSpec); - - GroupAST::Node cv; - parseCvQualify(cv); - - TypeSpecifierAST::Node spec; - if (parseEnumSpecifier(spec) || parseClassSpecifier(spec)) { - spec->setCvQualify(cv); - - GroupAST::Node cv2; - parseCvQualify(cv2); - spec->setCv2Qualify(cv2); - - InitDeclaratorListAST::Node declarators; - parseInitDeclaratorList(declarators); - if (!advance(';', ";")) - return false; - - if (!comment.isEmpty()) { - //uDebug() << "Parser::parseMemberSpecification(spec): comment is " << comment; - spec->setComment(comment); - } - - SimpleDeclarationAST::Node ast = CreateNode(); - ast->setTypeSpec(spec); - ast->setInitDeclaratorList(declarators); - update_pos(ast, start, m_tokenIt); - node = ast; - - return true; - } - - m_tokenIt = start; - - bool success = parseDeclarationInternal(node, comment); - if (success && !comment.isEmpty()) { - node->setComment(comment); - //uDebug() << "Parser::parseMemberSpecification(): comment is " << comment; - } - return success; -} - -bool Parser::parseCtorInitializer(AST::Node& /*node*/) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseCtorInitializer()"; - - if ((*m_tokenIt) != ':') { - return false; - } - ++m_tokenIt; - - AST::Node inits; - if (!parseMemInitializerList(inits)) { - reportError(i18n("Member initializers expected")); - } - - return true; -} - -bool Parser::parseElaboratedTypeSpecifier(TypeSpecifierAST::Node& node) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseElaboratedTypeSpecifier()"; - - TokenIterator start = m_tokenIt; - - int tk = (*m_tokenIt); - if (tk == Token_class || - tk == Token_struct || - tk == Token_union || - tk == Token_enum || - tk == Token_typename) { - AST::Node kind = CreateNode(); - ++m_tokenIt; - update_pos(kind, start, m_tokenIt); - - NameAST::Node name; - - if (parseName(name)) { - ElaboratedTypeSpecifierAST::Node ast = CreateNode(); - ast->setKind(kind); - ast->setName(name); - update_pos(ast, start, m_tokenIt); - node = ast; - - return true; - } - } - - m_tokenIt = start; - return false; -} - -bool Parser::parseDeclaratorId(NameAST::Node& node) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseDeclaratorId()"; - return parseName(node); -} - -bool Parser::parseExceptionSpecification(GroupAST::Node& node) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseExceptionSpecification()"; - - if ((*m_tokenIt) != Token_throw) { - return false; - } - ++m_tokenIt; - - if (!advance('(', "(")) - return false; - if ((*m_tokenIt) == Token_ellipsis) { - // extension found in MSVC++ 7.x headers - TokenIterator start = m_tokenIt; - GroupAST::Node ast = CreateNode(); - AST::Node ellipsis = ast_from_token(m_tokenIt); - ast->addNode(ellipsis); - ++m_tokenIt; - update_pos(ast, start, m_tokenIt); - node = ast; - } else { - parseTypeIdList(node); - } - if (!advance(')', ")")) - return false; - - return true; -} - -bool Parser::parseEnumerator(EnumeratorAST::Node& node) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseEnumerator()"; - - QString comment; - while ((*m_tokenIt) == Token_comment) { - comment += (*m_tokenIt).text(); - ++m_tokenIt; - } - if ((*m_tokenIt).isNull()) - return false; - - TokenIterator start = m_tokenIt; - - if ((*m_tokenIt) != Token_identifier) { - return false; - } - ++m_tokenIt; - - EnumeratorAST::Node ena = CreateNode(); - node = ena; - - AST::Node id = CreateNode(); - update_pos(id, start, m_tokenIt); - node->setId(id); - - if ((*m_tokenIt) == '=') { - ++m_tokenIt; - - AST::Node expr; - if (!parseConstantExpression(expr)) { - reportError(i18n("Constant expression expected")); - } - node->setExpr(expr); - } - - update_pos(node, start, m_tokenIt); - - return true; -} - -bool Parser::parseInitDeclarator(InitDeclaratorAST::Node& node) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseInitDeclarator()"; - - TokenIterator start = m_tokenIt; - - DeclaratorAST::Node decl; - AST::Node init; - if (!parseDeclarator(decl)) { - return false; - } - - parseInitializer(init); - - InitDeclaratorAST::Node ast = CreateNode(); - ast->setDeclarator(decl); - ast->setInitializer(init); - update_pos(ast, start, m_tokenIt); - node = ast; - - return true; -} - - - -bool Parser::parseBaseClause(BaseClauseAST::Node& node) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseBaseClause()"; - - TokenIterator start = m_tokenIt; - if ((*m_tokenIt) != ':') { - return false; - } - ++m_tokenIt; - - BaseClauseAST::Node bca = CreateNode(); - - BaseSpecifierAST::Node baseSpec; - if (parseBaseSpecifier(baseSpec)) { - bca->addBaseSpecifier(baseSpec); - - QString comment; - while ((*m_tokenIt) == ',') { - comment.clear(); - advanceAndCheckTrailingComment(comment); - - if (!parseBaseSpecifier(baseSpec)) { - reportError(i18n("Base class specifier expected")); - return false; - } - if (!comment.isEmpty()) - baseSpec->setComment(comment); - bca->addBaseSpecifier(baseSpec); - } - } else - return false; - - update_pos(bca, start, m_tokenIt); - node = bca; - - return true; -} - -bool Parser::parseInitializer(AST::Node& node) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseInitializer()"; - - if ((*m_tokenIt) == '=') { - ++m_tokenIt; - - AST::Node init; - if (!parseInitializerClause(node)) { - reportError(i18n("Initializer clause expected")); - return false; - } - } else if ((*m_tokenIt) == '(') { - ++m_tokenIt; - AST::Node expr; - skipCommaExpression(expr); - - if (!advance(')', ")")) - return false; - } - - return false; -} - -bool Parser::parseMemInitializerList(AST::Node& /*node*/) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseMemInitializerList()"; - - AST::Node init; - if (!parseMemInitializer(init)) { - return false; - } - - QString comment; - while ((*m_tokenIt) == ',') { - comment.clear(); - advanceAndCheckTrailingComment(comment); - - if (parseMemInitializer(init)) { - } else { - break; - } - } - - return true; -} - -bool Parser::parseMemInitializer(AST::Node& /*node*/) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseMemInitializer()"; - - NameAST::Node initId; - if (!parseMemInitializerId(initId)) { - reportError(i18n("Identifier expected")); - return false; - } - if (!advance('(', "(")) - return false; - AST::Node expr; - skipCommaExpression(expr); - if (!advance(')', ")")) - return false; - - return true; -} - -bool Parser::parseTypeIdList(GroupAST::Node& node) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseTypeIdList()"; - - TokenIterator start = m_tokenIt; - - AST::Node typeId; - if (!parseTypeId(typeId)) { - return false; - } - - GroupAST::Node ast = CreateNode(); - ast->addNode(typeId); - - QString comment; - while ((*m_tokenIt) == ',') { - comment.clear(); - advanceAndCheckTrailingComment(comment); - if (parseTypeId(typeId)) { - if (!comment.isEmpty()) - typeId->setComment(comment); - ast->addNode(typeId); - } else { - reportError(i18n("Type id expected")); - break; - } - } - - update_pos(ast, start, m_tokenIt); - node = ast; - return true; -} - -bool Parser::parseBaseSpecifier(BaseSpecifierAST::Node& node) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseBaseSpecifier()"; - - TokenIterator start = m_tokenIt; - BaseSpecifierAST::Node ast = CreateNode(); - - AST::Node access; - if ((*m_tokenIt) == Token_virtual) { - AST::Node virt = ast_from_token(m_tokenIt); - ast->setIsVirtual(virt); - - ++m_tokenIt; - - parseAccessSpecifier(access); - } else { - parseAccessSpecifier(access); - - if ((*m_tokenIt) == Token_virtual) { - AST::Node virt = ast_from_token(m_tokenIt); - ast->setIsVirtual(virt); - ++m_tokenIt; - } - } - - NameAST::Node name; - if (!parseName(name)) { - reportError(i18n("Class name expected")); - } - - ast->setAccess(access); - ast->setName(name); - update_pos(ast, start, m_tokenIt); - node = ast; - - return true; -} - - -bool Parser::parseInitializerClause(AST::Node& node) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseInitializerClause()"; - - if ((*m_tokenIt) == '{') { - if (!skip('{', '}')) { - reportError(i18n("} missing")); - } else - ++m_tokenIt; - } else { - if (!parseAssignmentExpression(node)) { - //reportError(i18n("Expression expected")); - } - } - - return true; -} - -bool Parser::parseMemInitializerId(NameAST::Node& node) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseMemInitializerId()"; - - return parseName(node); -} - -bool Parser::parsePtrToMember(AST::Node& /*node*/) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parsePtrToMember()"; - - if ((*m_tokenIt) == Token_scope) { - ++m_tokenIt; - } - - while ((*m_tokenIt) == Token_identifier) { - ++m_tokenIt; - - if ((*m_tokenIt) == Token_scope && lex->lookAhead(m_tokenIt, 1) == '*') { - ++m_tokenIt; // skip :: - ++m_tokenIt; // skip * - return true; - } else - break; - } - - return false; -} - -bool Parser::parseUnqualifiedName(ClassOrNamespaceNameAST::Node& node) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseUnqualifiedName()"; - - TokenIterator start = m_tokenIt; - bool isDestructor = false; - - ClassOrNamespaceNameAST::Node ast = CreateNode(); - - if ((*m_tokenIt) == Token_identifier) { - TokenIterator startName = m_tokenIt; - AST::Node n = CreateNode(); - ++m_tokenIt; - update_pos(n, startName, m_tokenIt); - ast->setName(n); - } else if ((*m_tokenIt) == '~' && lex->lookAhead(m_tokenIt, 1) == Token_identifier) { - TokenIterator startName = m_tokenIt; - AST::Node n = CreateNode(); - ++m_tokenIt; // skip ~ - ++m_tokenIt; // skip classname - update_pos(n, startName, m_tokenIt); - ast->setName(n); - isDestructor = true; - } else if ((*m_tokenIt) == Token_operator) { - AST::Node n; - if (!parseOperatorFunctionId(n)) - return false; - ast->setName(n); - } else { - return false; - } - - if (!isDestructor) { - - TokenIterator index = m_tokenIt; - - if ((*m_tokenIt) == '<') { - ++m_tokenIt; - - // optional template arguments - TemplateArgumentListAST::Node args; - parseTemplateArgumentList(args); - - if ((*m_tokenIt) != '>') { - m_tokenIt = index; - } else { - ++m_tokenIt; - ast->setTemplateArgumentList(args); - } - } - } - - update_pos(ast, start, m_tokenIt); - node = ast; - - return true; -} - -bool Parser::parseStringLiteral(AST::Node& /*node*/) -{ - while (!(*m_tokenIt).isNull()) { - if ((*m_tokenIt) == Token_identifier && - (*m_tokenIt).text() == "L" && lex->lookAhead(m_tokenIt, 1) == Token_string_literal) { - - ++m_tokenIt; - ++m_tokenIt; - } else if ((*m_tokenIt) == Token_string_literal) { - ++m_tokenIt; - } else - return false; - } - return true; -} - -bool Parser::skipExpressionStatement(StatementAST::Node& node) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::skipExpressionStatement()"; - - TokenIterator start = m_tokenIt; - - AST::Node expr; - skipCommaExpression(expr); - - if (!advance(';', ";")) - return false; - - ExpressionStatementAST::Node ast = CreateNode(); - ast->setExpression(expr); - update_pos(ast, start, m_tokenIt); - node = ast; - - return true; -} - -bool Parser::parseStatement(StatementAST::Node& node) // thanks to fiore@8080.it ;) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseStatement()"; - switch ((*m_tokenIt)) { - - case Token_while: - return parseWhileStatement(node); - - case Token_do: - return parseDoStatement(node); - - case Token_for: - return parseForStatement(node); - - case Token_if: - return parseIfStatement(node); - - case Token_switch: - return parseSwitchStatement(node); - - case Token_try: - return parseTryBlockStatement(node); - - case Token_case: - case Token_default: - return parseLabeledStatement(node); - - case Token_break: - case Token_continue: - ++m_tokenIt; - if (!advance(';', ";")) - return false; - return true; - - case Token_goto: - ++m_tokenIt; - if (!advance(Token_identifier, "identifier")) - return false; - if (!advance(';', ";")) - return false; - return true; - - case Token_return: { - ++m_tokenIt; - AST::Node expr; - skipCommaExpression(expr); - if (!advance(';', ";")) - return false; - } - return true; - - case '{': - return parseCompoundStatement(node); - - case Token_identifier: - if (parseLabeledStatement(node)) - return true; - break; - } - - //uDebug() << "------------> try with declaration statement"; - if (parseDeclarationStatement(node)) - return true; - - return skipExpressionStatement(node); -} - -bool Parser::parseCondition(ConditionAST::Node& node) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseCondition()"; - - TokenIterator start = m_tokenIt; - - ConditionAST::Node ast = CreateNode(); - - TypeSpecifierAST::Node spec; - if (parseTypeSpecifier(spec)) { - DeclaratorAST::Node decl; - if (parseDeclarator(decl) && (*m_tokenIt) == '=') { - ++m_tokenIt; - - AST::Node expr; - if (skipExpression(expr)) { - ast->setTypeSpec(spec); - ast->setDeclarator(decl); - ast->setExpression(expr); - - update_pos(ast, start, m_tokenIt); - node = ast; - - return true; - } - } - } - - m_tokenIt = start; - - AST::Node expr; - if (!skipCommaExpression(expr)) - return false; - - ast->setExpression(expr); - update_pos(ast, start, m_tokenIt); - node = ast; - return true; -} - - -bool Parser::parseWhileStatement(StatementAST::Node& node) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseWhileStatement()"; - TokenIterator start = m_tokenIt; - - if (!advance(Token_while, "while")) - return false; - if (!advance('(', "(")) - return false; - - ConditionAST::Node cond; - if (!parseCondition(cond)) { - reportError(i18n("condition expected")); - return false; - } - if (!advance(')', ")")) - return false; - - StatementAST::Node body; - if (!parseStatement(body)) { - reportError(i18n("statement expected")); - return false; - } - - WhileStatementAST::Node ast = CreateNode(); - ast->setCondition(cond); - ast->setStatement(body); - update_pos(ast, start, m_tokenIt); - node = ast; - - return true; -} - -bool Parser::parseDoStatement(StatementAST::Node& node) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseDoStatement()"; - TokenIterator start = m_tokenIt; - - if (!advance(Token_do, "do")) - return false; - - StatementAST::Node body; - if (!parseStatement(body)) { - reportError(i18n("statement expected")); - //return false; - } - - advance_nr(Token_while, "while"); - advance_nr('(', "("); - - AST::Node expr; - if (!skipCommaExpression(expr)) { - reportError(i18n("expression expected")); - //return false; - } - - advance_nr(')', ")"); - advance_nr(';', ";"); - - DoStatementAST::Node ast = CreateNode(); - ast->setStatement(body); - //ast->setCondition(condition); - update_pos(ast, start, m_tokenIt); - node = ast; - - return true; -} - -bool Parser::parseForStatement(StatementAST::Node& node) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseForStatement()"; - TokenIterator start = m_tokenIt; - - if (!advance(Token_for, "for")) - return false; - if (!advance('(', "(")) - return false; - - StatementAST::Node init; - if (!parseForInitStatement(init)) { - reportError(i18n("for initialization expected")); - return false; - } - - ConditionAST::Node cond; - parseCondition(cond); - if (!advance(';', ";")) - return false; - - AST::Node expr; - skipCommaExpression(expr); - if (!advance(')', ")")) - return false; - - StatementAST::Node body; - if (!parseStatement(body)) - return false; - - ForStatementAST::Node ast = CreateNode(); - ast->setInitStatement(init); - ast->setCondition(cond); - // ast->setExpression(expression); - ast->setStatement(body); - update_pos(ast, start, m_tokenIt); - node = ast; - - return true; -} - -bool Parser::parseForInitStatement(StatementAST::Node& node) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseForInitStatement()"; - - if (parseDeclarationStatement(node)) - return true; - - return skipExpressionStatement(node); -} - -bool Parser::parseCompoundStatement(StatementAST::Node& node) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseCompoundStatement()"; - TokenIterator start = m_tokenIt; - - if ((*m_tokenIt) != '{') { - return false; - } - ++m_tokenIt; - - StatementListAST::Node ast = CreateNode(); - - while (!(*m_tokenIt).isNull()) { - if ((*m_tokenIt) == '}') - break; - - StatementAST::Node stmt; - TokenIterator startStmt = m_tokenIt; - if (!parseStatement(stmt)) { - if (startStmt == m_tokenIt) - ++m_tokenIt; - skipUntilStatement(); - } else { - ast->addStatement(stmt); - } - } - - if ((*m_tokenIt) != '}') { - reportError(i18n("} expected")); - } else { - ++m_tokenIt; - } - - update_pos(ast, start, m_tokenIt); - node = ast; - - return true; -} - -bool Parser::parseIfStatement(StatementAST::Node& node) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseIfStatement()"; - - TokenIterator start = m_tokenIt; - - if (!advance(Token_if, "if")) - return false; - - if (!advance('(', "(")) - return false; - - IfStatementAST::Node ast = CreateNode(); - - ConditionAST::Node cond; - if (!parseCondition(cond)) { - reportError(i18n("condition expected")); - return false; - } - if (!advance(')', ")")) - return false; - - StatementAST::Node stmt; - if (!parseStatement(stmt)) { - reportError(i18n("statement expected")); - return false; - } - - ast->setCondition(cond); - ast->setStatement(stmt); - - if ((*m_tokenIt) == Token_else) { - ++m_tokenIt; - StatementAST::Node elseStmt; - if (!parseStatement(elseStmt)) { - reportError(i18n("statement expected")); - return false; - } - ast->setElseStatement(elseStmt); - } - - update_pos(ast, start, m_tokenIt); - node = ast; - - return true; -} - -bool Parser::parseSwitchStatement(StatementAST::Node& node) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseSwitchStatement()"; - TokenIterator start = m_tokenIt; - if (!advance(Token_switch, "switch")) - return false; - - if (!advance('(', "(")) - return false; - - ConditionAST::Node cond; - if (!parseCondition(cond)) { - reportError(i18n("condition expected")); - return false; - } - if (!advance(')', ")")) - return false; - - StatementAST::Node stmt; - if (!parseCompoundStatement(stmt)) { - syntaxError(); - return false; - } - - SwitchStatementAST::Node ast = CreateNode(); - ast->setCondition(cond); - ast->setStatement(stmt); - update_pos(ast, start, m_tokenIt); - node = ast; - - return true; -} - -bool Parser::parseLabeledStatement(StatementAST::Node& node) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseLabeledStatement()"; - switch ((*m_tokenIt)) { - case Token_identifier: - case Token_default: - if (lex->lookAhead(m_tokenIt, 1) == ':') { - ++m_tokenIt; - ++m_tokenIt; - - StatementAST::Node stmt; - if (parseStatement(stmt)) { - node = stmt; - return true; - } - } - break; - - case Token_case: { - ++m_tokenIt; - AST::Node expr; - if (!parseConstantExpression(expr)) { - reportError(i18n("expression expected")); - } else if ((*m_tokenIt) == Token_ellipsis) { - ++m_tokenIt; - - AST::Node expr2; - if (!parseConstantExpression(expr2)) { - reportError(i18n("expression expected")); - } - } - if (!advance(':', ":")) - return false; - - StatementAST::Node stmt; - if (parseStatement(stmt)) { - node = stmt; - return true; - } - } - break; - - } - - return false; -} - -bool Parser::parseBlockDeclaration(DeclarationAST::Node& node) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseBlockDeclaration()"; - switch ((*m_tokenIt)) { - case Token_typedef: - return parseTypedef(node); - case Token_using: - return parseUsing(node); - case Token_asm: - return parseAsmDefinition(node); - case Token_namespace: - return parseNamespaceAliasDefinition(node); - } - - TokenIterator start = m_tokenIt; - - GroupAST::Node storageSpec; - parseStorageClassSpecifier(storageSpec); - - GroupAST::Node cv; - parseCvQualify(cv); - - TypeSpecifierAST::Node spec; - if (!parseTypeSpecifierOrClassSpec(spec)) { // replace with simpleTypeSpecifier?!?! - m_tokenIt = start; - return false; - } - spec->setCvQualify(cv); - - GroupAST::Node cv2; - parseCvQualify(cv2); - spec->setCv2Qualify(cv2); - - InitDeclaratorListAST::Node declarators; - parseInitDeclaratorList(declarators); - - if ((*m_tokenIt) != ';') { - m_tokenIt = start; - return false; - } - ++m_tokenIt; - - SimpleDeclarationAST::Node ast = CreateNode(); - ast->setTypeSpec(spec); - ast->setInitDeclaratorList(declarators); - update_pos(ast, start, m_tokenIt); - node = ast; - - return true; -} - -bool Parser::parseNamespaceAliasDefinition(DeclarationAST::Node& /*node*/) -{ - if ((*m_tokenIt) != Token_namespace) { - return false; - } - ++m_tokenIt; - - if (!advance(Token_identifier, "identifier")) - return false; - if (!advance('=', "=")) - return false; - - NameAST::Node name; - if (!parseName(name)) { - reportError(i18n("Namespace name expected")); - } - - if (!advance(';', ";")) - return false; - - return true; - -} - -bool Parser::parseDeclarationStatement(StatementAST::Node& node) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseDeclarationStatement()"; - - TokenIterator start = m_tokenIt; - - DeclarationAST::Node decl; - if (!parseBlockDeclaration(decl)) { - return false; - } - - DeclarationStatementAST::Node ast = CreateNode(); - ast->setDeclaration(decl); - update_pos(ast, start, m_tokenIt); - node = ast; - - //uDebug() << "---------------------> found a block declaration"; - return true; -} - -bool Parser::parseDeclarationInternal(DeclarationAST::Node& node, QString& comment) -{ - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseDeclarationInternal()"; - - TokenIterator start = m_tokenIt; - - // that is for the case '__declspec(dllexport) int ...' or - // '__declspec(dllexport) inline int ...', etc. - GroupAST::Node winDeclSpec; - parseWinDeclSpec(winDeclSpec); - - GroupAST::Node funSpec; - bool hasFunSpec = parseFunctionSpecifier(funSpec); - - GroupAST::Node storageSpec; - bool hasStorageSpec = parseStorageClassSpecifier(storageSpec); - - if (hasStorageSpec && !hasFunSpec) - hasFunSpec = parseFunctionSpecifier(funSpec); - - // that is for the case 'friend __declspec(dllexport) ....' - GroupAST::Node winDeclSpec2; - parseWinDeclSpec(winDeclSpec2); - - GroupAST::Node cv; - parseCvQualify(cv); - - TokenIterator index = m_tokenIt; - NameAST::Node name; - if (parseName(name) && (*m_tokenIt) == '(') { - // no type specifier, maybe a constructor or a cast operator?? - - m_tokenIt = index; - - InitDeclaratorAST::Node declarator; - if (parseInitDeclarator(declarator)) { - TokenIterator endSignature = m_tokenIt; - - switch ((*m_tokenIt)) { - case ';': { - ++m_tokenIt; - - InitDeclaratorListAST::Node declarators = CreateNode(); - - // update declarators position - if (declarator.get()) { - declarators->setStartPosition(declarator->getStartPosition()); - declarators->setEndPosition(declarator->getEndPosition()); - } - declarators->addInitDeclarator(declarator); - - SimpleDeclarationAST::Node ast = CreateNode(); - ast->setInitDeclaratorList(declarators); - ast->setText(toString(start, endSignature)); - node = ast; - update_pos(node, start, m_tokenIt); - return true; - - } - break; - - case ':': { - AST::Node ctorInit; - StatementListAST::Node funBody; - if (parseCtorInitializer(ctorInit) && parseFunctionBody(funBody)) { - FunctionDefinitionAST::Node ast = CreateNode(); - ast->setStorageSpecifier(storageSpec); - ast->setFunctionSpecifier(funSpec); - ast->setInitDeclarator(declarator); - ast->setFunctionBody(funBody); - ast->setText(toString(start, endSignature)); - node = ast; - update_pos(node, start, m_tokenIt); - return true; - } - } - break; - - case '{': { - StatementListAST::Node funBody; - if (parseFunctionBody(funBody)) { - FunctionDefinitionAST::Node ast = CreateNode(); - ast->setStorageSpecifier(storageSpec); - ast->setFunctionSpecifier(funSpec); - ast->setInitDeclarator(declarator); - ast->setText(toString(start, endSignature)); - ast->setFunctionBody(funBody); - node = ast; - update_pos(node, start, m_tokenIt); - return true; - } - } - break; - - case '(': - case '[': - // ops!! it seems a declarator - goto start_decl; - break; - } - - } - - syntaxError(); - return false; -} - -start_decl: -m_tokenIt = index; - -if ((*m_tokenIt) == Token_const && lex->lookAhead(m_tokenIt, 1) == Token_identifier && lex->lookAhead(m_tokenIt, 2) == '=') { - // constant definition - ++m_tokenIt; - InitDeclaratorListAST::Node declarators; - if (parseInitDeclaratorList(declarators)) { - if (!advance(';', ";")) - return false; - DeclarationAST::Node ast = CreateNode(); - node = ast; - update_pos(node, start, m_tokenIt); - return true; - } - syntaxError(); - return false; -} - -TypeSpecifierAST::Node spec; -if (parseTypeSpecifier(spec)) { - if (!hasFunSpec) - parseFunctionSpecifier(funSpec); // e.g. "void inline" - spec->setCvQualify(cv); - - InitDeclaratorListAST::Node declarators; - - InitDeclaratorAST::Node decl; - TokenIterator startDeclarator = m_tokenIt; - bool maybeFunctionDefinition = false; - - if ((*m_tokenIt) != ';') { - if (parseInitDeclarator(decl) && (*m_tokenIt) == '{') { - // function definition - maybeFunctionDefinition = true; - } else { - m_tokenIt = startDeclarator; - if (!parseInitDeclaratorList(declarators)) { - syntaxError(); - return false; - } - } - } - - TokenIterator endSignature = m_tokenIt; - switch ((*m_tokenIt)) { - case ';': { - advanceAndCheckTrailingComment(comment); - SimpleDeclarationAST::Node ast = CreateNode(); - ast->setStorageSpecifier(storageSpec); - ast->setFunctionSpecifier(funSpec); - ast->setText(toString(start, endSignature)); - ast->setTypeSpec(spec); - ast->setWinDeclSpec(winDeclSpec); - ast->setInitDeclaratorList(declarators); - node = ast; - update_pos(node, start, m_tokenIt); - } - return true; - - case '{': { - if (!maybeFunctionDefinition) { - syntaxError(); - return false; - } - StatementListAST::Node funBody; - if (parseFunctionBody(funBody)) { - FunctionDefinitionAST::Node ast = CreateNode(); - ast->setWinDeclSpec(winDeclSpec); - ast->setStorageSpecifier(storageSpec); - ast->setFunctionSpecifier(funSpec); - ast->setText(toString(start, endSignature)); - ast->setTypeSpec(spec); - ast->setFunctionBody(funBody); - ast->setInitDeclarator(decl); - node = ast; - update_pos(node, start, m_tokenIt); - return true; - } - } - break; - - } -} - -syntaxError(); -return false; -} - -bool Parser::parseFunctionBody(StatementListAST::Node& node) -{ -//uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseFunctionBody()"; - -TokenIterator start = m_tokenIt; -if ((*m_tokenIt) != '{') { - return false; -} -++m_tokenIt; - -StatementListAST::Node ast = CreateNode(); - -while (!(*m_tokenIt).isNull()) { - if ((*m_tokenIt) == '}') - break; - - StatementAST::Node stmt; - TokenIterator startStmt = m_tokenIt; - if (!parseStatement(stmt)) { - if (startStmt == m_tokenIt) - ++m_tokenIt; - skipUntilStatement(); - } else - ast->addStatement(stmt); -} - -if ((*m_tokenIt) != '}') { - reportError(i18n("} expected")); -} else - ++m_tokenIt; - -update_pos(ast, start, m_tokenIt); -node = ast; - -return true; -} - -QString Parser::toString(TokenIterator start, TokenIterator end, - const QString& sep) const -{ -QStringList l; - -for (; start != end; ++start) { - l << (*start).text(); -} - -return l.join(sep).trimmed(); -} - -bool Parser::parseTypeSpecifierOrClassSpec(TypeSpecifierAST::Node& node) -{ -if (parseClassSpecifier(node)) - return true; -else if (parseEnumSpecifier(node)) - return true; -else if (parseTypeSpecifier(node)) - return true; - -return false; -} - -bool Parser::parseTryBlockStatement(StatementAST::Node& node) -{ -//uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseTryBlockStatement()"; - -if ((*m_tokenIt) != Token_try) { - return false; -} -++m_tokenIt; - -StatementAST::Node stmt; -if (!parseCompoundStatement(stmt)) { - syntaxError(); - return false; -} - -if ((*m_tokenIt) != Token_catch) { - reportError(i18n("catch expected")); - return false; -} - -while ((*m_tokenIt) == Token_catch) { - ++m_tokenIt; - if (!advance('(', "(")) - return false; - ConditionAST::Node cond; - if (!parseCondition(cond)) { - reportError(i18n("condition expected")); - return false; - } - if (!advance(')', ")")) - return false; - - StatementAST::Node body; - if (!parseCompoundStatement(body)) { - syntaxError(); - return false; - } -} - -node = stmt; -return true; -} - -bool Parser::parsePrimaryExpression(AST::Node& /*node*/) -{ -//uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parsePrimarExpression()"; - - -switch ((*m_tokenIt)) { -case Token_string_literal: { - AST::Node lit; - parseStringLiteral(lit); - } - return true; - -case Token_number_literal: -case Token_char_literal: -case Token_true: -case Token_false: - ++m_tokenIt; - return true; - -case Token_this: - ++m_tokenIt; - return true; - -case Token_dynamic_cast: -case Token_static_cast: -case Token_reinterpret_cast: -case Token_const_cast: { - ++m_tokenIt; - - if (! check('<')) - return false; - AST::Node typeId; - parseTypeId(typeId); - if (! check('>')) - return false; - - if (! check('(')) - return false; - AST::Node expr; - parseCommaExpression(expr); - if (! check(')')) - return false; - } - return true; - -case Token_typeid: { - ++m_tokenIt; - if (! check('(')) - return false; - AST::Node expr; - parseCommaExpression(expr); - if (! check(')')) - return false; - } - return true; - -case '(': { - ++m_tokenIt; - //uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "token = " << (*m_tokenIt).text(); - AST::Node expr; - if (!parseExpression(expr)) { - return false; - } - if (! check(')')) - return false; - } - return true; - -default: { - TokenIterator start = m_tokenIt; - TypeSpecifierAST::Node typeSpec; - if (parseSimpleTypeSpecifier(typeSpec) && (*m_tokenIt) == '(') { - ++m_tokenIt; - AST::Node expr; - parseCommaExpression(expr); - if (! check(')')) - return false; - return true; - } - - m_tokenIt = start; - NameAST::Node name; - if (parseName(name)) - return true; - } -} - -return false; -} - -bool Parser::parsePostfixExpression(AST::Node& /*node*/) -{ -//uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parsePostfixExpression()"; - -AST::Node expr; -if (!parsePrimaryExpression(expr)) - return false; - -while (true) { - switch ((*m_tokenIt)) { - case '[': { - ++m_tokenIt; - AST::Node e; - parseCommaExpression(e); - if (! check(']')) - return false; - } - break; - - case '(': { - ++m_tokenIt; - AST::Node funArgs; - parseCommaExpression(funArgs); - if (! check(')')) - return false; - } - break; - - case Token_incr: - case Token_decr: - ++m_tokenIt; - break; - - case '.': - case Token_arrow: { - ++m_tokenIt; - if ((*m_tokenIt) == Token_template) - ++m_tokenIt; - - NameAST::Node name; - if (!parseName(name)) { - return false; - } - } - break; - - case Token_typename: { - ++m_tokenIt; - - NameAST::Node name; - if (!parseName(name)) { - return false; - } - - if (! check('(')) - return false; - AST::Node expr; - parseCommaExpression(expr); - if (! check(')')) - return false; - } - return true; - - default: - return true; - - } // end switch - -} // end while - -return true; -} - -bool Parser::parseUnaryExpression(AST::Node& node) -{ -//uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseUnaryExpression()"; - -switch ((*m_tokenIt)) { -case Token_incr: -case Token_decr: -case '*': -case '&': -case '+': -case '-': -case '!': -case '~': { - ++m_tokenIt; - AST::Node expr; - return parseCastExpression(expr); - } - -case Token_sizeof: { - ++m_tokenIt; - TokenIterator index = m_tokenIt; - if ((*m_tokenIt) == '(') { - ++m_tokenIt; - AST::Node typeId; - if (parseTypeId(typeId) && (*m_tokenIt) == ')') { - ++m_tokenIt; - return true; - } - m_tokenIt = index; - } - AST::Node expr; - return parseUnaryExpression(expr); - } - -case Token_new: - return parseNewExpression(node); - -case Token_delete: - return parseDeleteExpression(node); -} - -return parsePostfixExpression(node); -} - -bool Parser::parseNewExpression(AST::Node& /*node*/) -{ -//uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseNewExpression()"; -if ((*m_tokenIt) == Token_scope && lex->lookAhead(m_tokenIt, 1) == Token_new) - ++m_tokenIt; - -if (! check(Token_new)) - return false; - -if ((*m_tokenIt) == '(') { - ++m_tokenIt; - AST::Node expr; - parseCommaExpression(expr); - if (! check(')')) - return false; -} - -if ((*m_tokenIt) == '(') { - ++m_tokenIt; - AST::Node typeId; - parseTypeId(typeId); - if (! check(')')) - return false; -} else { - AST::Node typeId; - parseNewTypeId(typeId); -} - -AST::Node init; -parseNewInitializer(init); -return true; -} - -bool Parser::parseNewTypeId(AST::Node& /*node*/) -{ -//uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseNewTypeId()"; -TypeSpecifierAST::Node typeSpec; -if (parseTypeSpecifier(typeSpec)) { - AST::Node declarator; - parseNewDeclarator(declarator); - return true; -} - -return false; -} - -bool Parser::parseNewDeclarator(AST::Node& /*node*/) -{ -//uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseNewDeclarator()"; -AST::Node ptrOp; -if (parsePtrOperator(ptrOp)) { - AST::Node declarator; - parseNewDeclarator(declarator); - return true; -} - -if ((*m_tokenIt) == '[') { - while ((*m_tokenIt) == '[') { - ++m_tokenIt; - AST::Node expr; - parseExpression(expr); - if (!advance(']', "]")) - return false; - } - return true; -} - -return false; -} - -bool Parser::parseNewInitializer(AST::Node& /*node*/) -{ -//uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseNewInitializer()"; -if ((*m_tokenIt) != '(') - return false; - -++m_tokenIt; -AST::Node expr; -parseCommaExpression(expr); -if (! check(')')) - return false; - -return true; -} - -bool Parser::parseDeleteExpression(AST::Node& /*node*/) -{ -//uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseDeleteExpression()"; -if ((*m_tokenIt) == Token_scope && lex->lookAhead(m_tokenIt, 1) == Token_delete) - ++m_tokenIt; - -if (! check(Token_delete)) - return false; - -if ((*m_tokenIt) == '[') { - ++m_tokenIt; - if (! check(']')) - return false; -} - -AST::Node expr; -return parseCastExpression(expr); -} - -bool Parser::parseCastExpression(AST::Node& /*node*/) -{ -//uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseCastExpression()"; - -TokenIterator index = m_tokenIt; - -if ((*m_tokenIt) == '(') { - ++m_tokenIt; - AST::Node typeId; - if (parseTypeId(typeId)) { - if ((*m_tokenIt) == ')') { - ++m_tokenIt; - AST::Node expr; - if (parseCastExpression(expr)) - return true; - } - } -} - -m_tokenIt = index; - -AST::Node expr; -return parseUnaryExpression(expr); -} - -bool Parser::parsePmExpression(AST::Node& /*node*/) -{ -//uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser:parsePmExpression()"; -AST::Node expr; -if (!parseCastExpression(expr)) - return false; - -while ((*m_tokenIt) == Token_ptrmem) { - ++m_tokenIt; - - if (!parseCastExpression(expr)) - return false; -} - -return true; -} - -bool Parser::parseMultiplicativeExpression(AST::Node& /*node*/) -{ -//uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseMultiplicativeExpression()"; -AST::Node expr; -if (!parsePmExpression(expr)) - return false; - -while ((*m_tokenIt) == '*' || (*m_tokenIt) == '/' || (*m_tokenIt) == '%') { - ++m_tokenIt; - - if (!parsePmExpression(expr)) - return false; -} - -return true; -} - - -bool Parser::parseAdditiveExpression(AST::Node& /*node*/) -{ -//uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseAdditiveExpression()"; -AST::Node expr; -if (!parseMultiplicativeExpression(expr)) - return false; - -while ((*m_tokenIt) == '+' || (*m_tokenIt) == '-') { - ++m_tokenIt; - - if (!parseMultiplicativeExpression(expr)) - return false; -} - -return true; -} - -bool Parser::parseShiftExpression(AST::Node& /*node*/) -{ -//uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseShiftExpression()"; -AST::Node expr; -if (!parseAdditiveExpression(expr)) - return false; - -if ((*m_tokenIt) == '>') { - uWarning() << "TODO: add support for '>>'"; -} - -while ((*m_tokenIt) == Token_left_shift) { - ++m_tokenIt; - - if (!parseAdditiveExpression(expr)) - return false; -} - -return true; -} - -bool Parser::parseRelationalExpression(AST::Node& /*node*/, bool templArgs) -{ -//uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseRelationalExpression()"; -AST::Node expr; -if (!parseShiftExpression(expr)) - return false; - -while ((*m_tokenIt) == '<' || ((*m_tokenIt) == '>' && !templArgs) || - (*m_tokenIt) == Token_leq || (*m_tokenIt) == Token_geq) { - ++m_tokenIt; - - if (!parseShiftExpression(expr)) - return false; -} - -return true; -} - -bool Parser::parseEqualityExpression(AST::Node& /*node*/, bool templArgs) -{ -//uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseEqualityExpression()"; -AST::Node expr; -if (!parseRelationalExpression(expr, templArgs)) - return false; - -while ((*m_tokenIt) == Token_eq || (*m_tokenIt) == Token_not_eq) { - ++m_tokenIt; - - if (!parseRelationalExpression(expr, templArgs)) - return false; -} - -return true; -} - -bool Parser::parseAndExpression(AST::Node& /*node*/, bool templArgs) -{ -//uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseAndExpression()"; -AST::Node expr; -if (!parseEqualityExpression(expr, templArgs)) - return false; - -while ((*m_tokenIt) == '&') { - ++m_tokenIt; - - if (!parseEqualityExpression(expr, templArgs)) - return false; -} - -return true; -} - -bool Parser::parseExclusiveOrExpression(AST::Node& /*node*/, bool templArgs) -{ -//uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseExclusiveOrExpression()"; -AST::Node expr; -if (!parseAndExpression(expr, templArgs)) - return false; - -while ((*m_tokenIt) == '^') { - ++m_tokenIt; - - if (!parseAndExpression(expr, templArgs)) - return false; -} - -return true; -} - -bool Parser::parseInclusiveOrExpression(AST::Node& /*node*/, bool templArgs) -{ -//uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseInclusiveOrExpression()"; -AST::Node expr; -if (!parseExclusiveOrExpression(expr, templArgs)) - return false; - -while ((*m_tokenIt) == '|') { - ++m_tokenIt; - - if (!parseExclusiveOrExpression(expr, templArgs)) - return false; -} - -return true; -} - -bool Parser::parseLogicalAndExpression(AST::Node& /*node*/, bool templArgs) -{ -//uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseLogicalAndExpression()"; - -AST::Node expr; -if (!parseInclusiveOrExpression(expr, templArgs)) - return false; - -while ((*m_tokenIt) == Token_and) { - ++m_tokenIt; - - if (!parseInclusiveOrExpression(expr, templArgs)) - return false; -} - -return true; -} - -bool Parser::parseLogicalOrExpression(AST::Node& node, bool templArgs) -{ -//uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseLogicalOrExpression()"; - -TokenIterator start = m_tokenIt; - -AST::Node expr; -if (!parseLogicalAndExpression(expr, templArgs)) - return false; - -while ((*m_tokenIt) == Token_or) { - ++m_tokenIt; - - if (!parseLogicalAndExpression(expr, templArgs)) - return false; -} - -AST::Node ast = CreateNode(); -update_pos(ast, start, m_tokenIt); -node = ast; -return true; -} - -bool Parser::parseConditionalExpression(AST::Node& /*node*/) -{ -//uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseConditionalExpression()"; -AST::Node expr; -if (!parseLogicalOrExpression(expr)) - return false; - -if ((*m_tokenIt) == '?') { - ++m_tokenIt; - - if (!parseExpression(expr)) - return false; - - if (! check(':')) - return false; - - if (!parseAssignmentExpression(expr)) - return false; -} - -return true; -} - -bool Parser::parseAssignmentExpression(AST::Node& node) -{ -//uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseAssignmentExpression()"; -TokenIterator start = m_tokenIt; -AST::Node expr; -if ((*m_tokenIt) == Token_throw && !parseThrowExpression(expr)) - return false; -else if (!parseConditionalExpression(expr)) - return false; - -while ((*m_tokenIt) == Token_assign || (*m_tokenIt) == '=') { - ++m_tokenIt; - - if (!parseConditionalExpression(expr)) - return false; -} - -AST::Node ast = CreateNode(); -update_pos(ast, start, m_tokenIt); -node = ast; -return true; -} - -bool Parser::parseConstantExpression(AST::Node& node) -{ -//uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseConstantExpression()"; -TokenIterator start = m_tokenIt; -if (parseConditionalExpression(node)) { - AST::Node ast = CreateNode(); - update_pos(ast, start, m_tokenIt); - node = ast; - return true; -} -return false; -} - -bool Parser::parseExpression(AST::Node& node) -{ -//uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseExpression()"; - -TokenIterator start = m_tokenIt; - -if (!parseCommaExpression(node)) - return false; - -AST::Node ast = CreateNode(); -update_pos(ast, start, m_tokenIt); -node = ast; -return true; -} - -bool Parser::parseCommaExpression(AST::Node& node) -{ -//uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseCommaExpression()"; -TokenIterator start = m_tokenIt; - -AST::Node expr; -if (!parseAssignmentExpression(expr)) - return false; - -QString comment; -while ((*m_tokenIt) == ',') { - comment.clear(); - advanceAndCheckTrailingComment(comment); - - if (!parseAssignmentExpression(expr)) - return false; - if (!comment.isEmpty()) - expr->setComment(comment); -} - -AST::Node ast = CreateNode(); -update_pos(ast, start, m_tokenIt); -node = ast; -return true; -} - -bool Parser::parseThrowExpression(AST::Node& /*node*/) -{ -//uDebug() << "--- tok = " << (*m_tokenIt).text() << " -- " << "Parser::parseThrowExpression()"; -if ((*m_tokenIt) != Token_throw) - return false; - -if (! check(Token_throw)) - return false; -AST::Node expr; -if (!parseAssignmentExpression(expr)) - return false; - -return true; -} - -bool Parser::parseIvarDeclList(AST::Node & node) -{ -Q_UNUSED(node); -return false; -} - -bool Parser::parseIvarDecls(AST::Node & node) -{ -Q_UNUSED(node); -return false; -} - -bool Parser::parseIvarDecl(AST::Node & node) -{ -Q_UNUSED(node); -return false; -} - -bool Parser::parseIvars(AST::Node & node) -{ -Q_UNUSED(node); -return false; -} - -bool Parser::parseIvarDeclarator(AST::Node & node) -{ -Q_UNUSED(node); -return false; -} - -bool Parser::parseMethodDecl(AST::Node & node) -{ -Q_UNUSED(node); -return false; -} - -bool Parser::parseUnarySelector(AST::Node & node) -{ -Q_UNUSED(node); -return false; -} - -bool Parser::parseKeywordSelector(AST::Node & node) -{ -Q_UNUSED(node); -return false; -} - -bool Parser::parseSelector(AST::Node & node) -{ -Q_UNUSED(node); -return false; -} - -bool Parser::parseKeywordDecl(AST::Node & node) -{ -Q_UNUSED(node); -return false; -} - -bool Parser::parseReceiver(AST::Node & node) -{ -Q_UNUSED(node); -return false; -} - -bool Parser::parseObjcMessageExpr(AST::Node & node) -{ -Q_UNUSED(node); -return false; -} - -bool Parser::parseMessageArgs(AST::Node & node) -{ -Q_UNUSED(node); -return false; -} - -bool Parser::parseKeywordExpr(AST::Node & node) -{ -Q_UNUSED(node); -return false; -} - -bool Parser::parseKeywordArgList(AST::Node & node) -{ -Q_UNUSED(node); -return false; -} - -bool Parser::parseKeywordArg(AST::Node & node) -{ -Q_UNUSED(node); -return false; -} - -bool Parser::parseReservedWord(AST::Node & node) -{ -Q_UNUSED(node); -return false; -} - -bool Parser::parseMyParms(AST::Node & node) -{ -Q_UNUSED(node); -return false; -} - -bool Parser::parseMyParm(AST::Node & node) -{ -Q_UNUSED(node); -return false; -} - -bool Parser::parseOptParmList(AST::Node & node) -{ -Q_UNUSED(node); -return false; -} - -bool Parser::parseObjcSelectorExpr(AST::Node & node) -{ -Q_UNUSED(node); -return false; -} - -bool Parser::parseSelectorArg(AST::Node & node) -{ -Q_UNUSED(node); -return false; -} - -bool Parser::parseKeywordNameList(AST::Node & node) -{ -Q_UNUSED(node); -return false; -} - -bool Parser::parseKeywordName(AST::Node & node) -{ -Q_UNUSED(node); -return false; -} - -bool Parser::parseObjcEncodeExpr(AST::Node & node) -{ -Q_UNUSED(node); -return false; -} - -bool Parser::parseObjcString(AST::Node & node) -{ -Q_UNUSED(node); -return false; -} - -bool Parser::parseProtocolRefs(AST::Node & node) -{ -Q_UNUSED(node); -return false; -} - -bool Parser::parseIdentifierList(GroupAST::Node & node) -{ -TokenIterator start = m_tokenIt; - -if ((*m_tokenIt) != Token_identifier) - return false; - -GroupAST::Node ast = CreateNode(); - -AST::Node tk = ast_from_token(m_tokenIt); -ast->addNode(tk); -++m_tokenIt; - -QString comment; -while ((*m_tokenIt) == ',') { - comment.clear(); - advanceAndCheckTrailingComment(comment); - if ((*m_tokenIt) == Token_identifier) { - AST::Node tk = ast_from_token(m_tokenIt); - ast->addNode(tk); - ++m_tokenIt; - } - if (!advance(Token_identifier, "identifier")) - return false; -} - -node = ast; -update_pos(node, start, m_tokenIt); -return true; -} - -bool Parser::parseIdentifierColon(AST::Node & node) -{ -Q_UNUSED(node); - -if ((*m_tokenIt) == Token_identifier && lex->lookAhead(m_tokenIt, 1) == ':') { - ++m_tokenIt; - ++m_tokenIt; - return true; -} // ### else if PTYPENAME -> return true ; - -return false; -} - -bool Parser::parseObjcProtocolExpr(AST::Node & node) -{ -Q_UNUSED(node); -return false; -} - -bool Parser::parseObjcOpenBracketExpr(AST::Node & node) -{ -Q_UNUSED(node); -return false; -} - -bool Parser::parseObjcCloseBracket(AST::Node & node) -{ -Q_UNUSED(node); -return false; -} - -bool Parser::parseObjcDef(DeclarationAST::Node & node) -{ -Q_UNUSED(node); -return false; -} - -bool Parser::parseObjcClassDef(DeclarationAST::Node & node) -{ -Q_UNUSED(node); -return false; -} - -bool Parser::parseObjcClassDecl(DeclarationAST::Node & node) -{ -Q_UNUSED(node); - -if (!advance(OBJC_CLASS, "@class")) - return false; - -GroupAST::Node idList; -parseIdentifierList(idList); -if (!advance(';', ";")) - return false; - -return true; -} - -bool Parser::parseObjcProtocolDecl(DeclarationAST::Node & node) -{ -Q_UNUSED(node); - -if (!advance(OBJC_PROTOCOL, "@protocol")) - return false; - -GroupAST::Node idList; -parseIdentifierList(idList); -if (!advance(';', ";")) - return false; - -return true; -} - -bool Parser::parseObjcAliasDecl(DeclarationAST::Node & node) -{ -Q_UNUSED(node); - -if (!advance(OBJC_ALIAS, "@alias")) - return false; - -GroupAST::Node idList; -parseIdentifierList(idList); -if (!advance(';', ";")) - return false; - -return true; -} - -bool Parser::parseObjcProtocolDef(DeclarationAST::Node & node) -{ -Q_UNUSED(node); -return false; -} - -bool Parser::parseObjcMethodDef(DeclarationAST::Node & node) -{ -Q_UNUSED(node); -return false; -} - -bool Parser::parseWinDeclSpec(GroupAST::Node & node) -{ -if ((*m_tokenIt) == Token_identifier && (*m_tokenIt).text() == "__declspec" && lex->lookAhead(m_tokenIt, 1) == '(') { - TokenIterator start = m_tokenIt; - ++m_tokenIt; - ++m_tokenIt; // skip '(' - - parseIdentifierList(node); - if (!advance(')', ")")) - return false; - - update_pos(node, start, m_tokenIt); - return true; -} - -return false; -} - diff -Nru umbrello-4.12.3/umbrello/codeimport/kdevcppparser/parser.h umbrello-4.12.90/umbrello/codeimport/kdevcppparser/parser.h --- umbrello-4.12.3/umbrello/codeimport/kdevcppparser/parser.h 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/codeimport/kdevcppparser/parser.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,241 +0,0 @@ -/* This file is part of KDevelop - Copyright (C) 2002, 2003 Roberto Raggi - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef PARSER_H -#define PARSER_H - -#include "ast.h" -#include "lexer.h" - -#include - -struct ParserPrivateData; - -class Driver; -class Lexer; -struct Error; - -class Parser -{ - typedef Lexer::TokenIterator TokenIterator; -public: - Parser(Driver* driver, Lexer* lexer); - virtual ~Parser(); - -private: - bool advance(int tk, char const* descr); - void advance_nr(int tk, char const* descr); - AST::Node ast_from_token(TokenIterator tk) const; - bool check(int tk); - virtual bool reportError(const Error& err); - /** @todo remove*/ virtual bool reportError(const QString& msg); - /** @todo remove*/ virtual void syntaxError(); - template - void update_pos(AUTO_PTR<_astType> const& node, TokenIterator start, TokenIterator end) const - { - Token const& a = *start; - TokenIterator l_tmp = end; - if(l_tmp != start) - --l_tmp; - Token const& b = *l_tmp; - node->setStartPosition(a.getStartPosition()); - node->setEndPosition(b.getEndPosition()); - if(node->nodeType() == NodeType_Generic) { - if (start == l_tmp) - node->setSlice(a.text()); - else - node->setText(toString(start, end)); - } - } - -public: /*rules*/ - - bool parseTranslationUnit(TranslationUnitAST::Node& node); - - bool parseDeclaration(DeclarationAST::Node& node); - bool parseBlockDeclaration(DeclarationAST::Node& node); - bool parseLinkageSpecification(DeclarationAST::Node& node); - bool parseLinkageBody(LinkageBodyAST::Node& node); - bool parseNamespace(DeclarationAST::Node& node); - bool parseNamespaceAliasDefinition(DeclarationAST::Node& node); - bool parseUsing(DeclarationAST::Node& node); - bool parseUsingDirective(DeclarationAST::Node& node); - bool parseTypedef(DeclarationAST::Node& node); - bool parseAsmDefinition(DeclarationAST::Node& node); - bool parseTemplateDeclaration(DeclarationAST::Node& node); - bool parseDeclarationInternal(DeclarationAST::Node& node, QString& comment); - - bool parseUnqualifiedName(ClassOrNamespaceNameAST::Node& node); - bool parseStringLiteral(AST::Node& node); - bool parseName(NameAST::Node& node); - bool parseOperatorFunctionId(AST::Node& node); - bool parseTemplateArgumentList(TemplateArgumentListAST::Node& node, bool reportError=true); - bool parseOperator(AST::Node& node); - bool parseCvQualify(GroupAST::Node& node); - bool parseSimpleTypeSpecifier(TypeSpecifierAST::Node& node); - bool parsePtrOperator(AST::Node& node); - bool parseTemplateArgument(AST::Node& node); - bool parseTypeSpecifier(TypeSpecifierAST::Node& node); - bool parseTypeSpecifierOrClassSpec(TypeSpecifierAST::Node& node); - bool parseDeclarator(DeclaratorAST::Node& node); - bool parseTemplateParameterList(TemplateParameterListAST::Node& node); - bool parseTemplateParameter(TemplateParameterAST::Node& node); - bool parseStorageClassSpecifier(GroupAST::Node& node); - bool parseFunctionSpecifier(GroupAST::Node& node); - bool parseInitDeclaratorList(InitDeclaratorListAST::Node& node); - bool parseInitDeclarator(InitDeclaratorAST::Node& node); - bool parseParameterDeclarationClause(ParameterDeclarationClauseAST::Node& node); - bool parseCtorInitializer(AST::Node& node); - bool parsePtrToMember(AST::Node& node); - bool parseEnumSpecifier(TypeSpecifierAST::Node& node); - bool parseClassSpecifier(TypeSpecifierAST::Node& node); - bool parseWinDeclSpec(GroupAST::Node& node); - bool parseElaboratedTypeSpecifier(TypeSpecifierAST::Node& node); - bool parseDeclaratorId(NameAST::Node& node); - bool parseExceptionSpecification(GroupAST::Node& node); - bool parseEnumerator(EnumeratorAST::Node& node); - bool parseTypeParameter(TypeParameterAST::Node& node); - bool parseParameterDeclaration(ParameterDeclarationAST::Node& node); - bool parseTypeId(AST::Node& node); - bool parseAbstractDeclarator(DeclaratorAST::Node& node); - bool parseParameterDeclarationList(ParameterDeclarationListAST::Node& node); - bool parseMemberSpecification(DeclarationAST::Node& node); - bool parseAccessSpecifier(AST::Node& node); - bool parseTypeIdList(GroupAST::Node& node); - bool parseMemInitializerList(AST::Node& node); - bool parseMemInitializer(AST::Node& node); - bool parseInitializer(AST::Node& node); - bool parseBaseClause(BaseClauseAST::Node& node); - bool parseBaseSpecifier(BaseSpecifierAST::Node& node); - bool parseInitializerClause(AST::Node& node); - bool parseMemInitializerId(NameAST::Node& node); - bool parseFunctionBody(StatementListAST::Node& node); - - // expression - bool skipExpression(AST::Node& node); - bool skipCommaExpression(AST::Node& node); - bool skipExpressionStatement(StatementAST::Node& node); - - bool parseExpression(AST::Node& node); - bool parsePrimaryExpression(AST::Node& node); - bool parsePostfixExpression(AST::Node& node); - bool parseUnaryExpression(AST::Node& node); - bool parseNewExpression(AST::Node& node); - bool parseNewTypeId(AST::Node& node); - bool parseNewDeclarator(AST::Node& node); - bool parseNewInitializer(AST::Node& node); - bool parseDeleteExpression(AST::Node& node); - bool parseCastExpression(AST::Node& node); - bool parsePmExpression(AST::Node& node); - bool parseMultiplicativeExpression(AST::Node& node); - bool parseAdditiveExpression(AST::Node& node); - bool parseShiftExpression(AST::Node& node); - bool parseRelationalExpression(AST::Node& node, bool templArgs=false); - bool parseEqualityExpression(AST::Node& node, bool templArgs=false); - bool parseAndExpression(AST::Node& node, bool templArgs=false); - bool parseExclusiveOrExpression(AST::Node& node, bool templArgs=false); - bool parseInclusiveOrExpression(AST::Node& node, bool templArgs=false); - bool parseLogicalAndExpression(AST::Node& node, bool templArgs=false); - bool parseLogicalOrExpression(AST::Node& node, bool templArgs=false); - bool parseConditionalExpression(AST::Node& node); - bool parseAssignmentExpression(AST::Node& node); - bool parseConstantExpression(AST::Node& node); - bool parseCommaExpression(AST::Node& node); - bool parseThrowExpression(AST::Node& node); - - // statement - bool parseCondition(ConditionAST::Node& node); - bool parseStatement(StatementAST::Node& node); - bool parseWhileStatement(StatementAST::Node& node); - bool parseDoStatement(StatementAST::Node& node); - bool parseForStatement(StatementAST::Node& node); - bool parseCompoundStatement(StatementAST::Node& node); - bool parseForInitStatement(StatementAST::Node& node); - bool parseIfStatement(StatementAST::Node& node); - bool parseSwitchStatement(StatementAST::Node& node); - bool parseLabeledStatement(StatementAST::Node& node); - bool parseDeclarationStatement(StatementAST::Node& node); - bool parseTryBlockStatement(StatementAST::Node& node); - - // objective c - bool parseObjcDef(DeclarationAST::Node& node); - bool parseObjcClassDef(DeclarationAST::Node& node); - bool parseObjcClassDecl(DeclarationAST::Node& node); - bool parseObjcProtocolDecl(DeclarationAST::Node& node); - bool parseObjcAliasDecl(DeclarationAST::Node& node); - bool parseObjcProtocolDef(DeclarationAST::Node& node); - bool parseObjcMethodDef(DeclarationAST::Node& node); - - bool parseIvarDeclList(AST::Node& node); - bool parseIvarDecls(AST::Node& node); - bool parseIvarDecl(AST::Node& node); - bool parseIvars(AST::Node& node); - bool parseIvarDeclarator(AST::Node& node); - bool parseMethodDecl(AST::Node& node); - bool parseUnarySelector(AST::Node& node); - bool parseKeywordSelector(AST::Node& node); - bool parseSelector(AST::Node& node); - bool parseKeywordDecl(AST::Node& node); - bool parseReceiver(AST::Node& node); - bool parseObjcMessageExpr(AST::Node& node); - bool parseMessageArgs(AST::Node& node); - bool parseKeywordExpr(AST::Node& node); - bool parseKeywordArgList(AST::Node& node); - bool parseKeywordArg(AST::Node& node); - bool parseReservedWord(AST::Node& node); - bool parseMyParms(AST::Node& node); - bool parseMyParm(AST::Node& node); - bool parseOptParmList(AST::Node& node); - bool parseObjcSelectorExpr(AST::Node& node); - bool parseSelectorArg(AST::Node& node); - bool parseKeywordNameList(AST::Node& node); - bool parseKeywordName(AST::Node& node); - bool parseObjcEncodeExpr(AST::Node& node); - bool parseObjcString(AST::Node& node); - bool parseProtocolRefs(AST::Node& node); - bool parseIdentifierList(GroupAST::Node& node); - bool parseIdentifierColon(AST::Node& node); - bool parseObjcProtocolExpr(AST::Node& node); - bool parseObjcOpenBracketExpr(AST::Node& node); - bool parseObjcCloseBracket(AST::Node& node); - - void advanceAndCheckTrailingComment(QString& comment); - - bool skipUntil(int token); - bool skipUntilDeclaration(); - bool skipUntilStatement(); - bool skip(int l, int r); - QString toString(TokenIterator start, TokenIterator end, const QString& sep=" ") const; - -private: - ParserPrivateData* d; - Driver* m_driver; - Lexer* lex; - int m_problems; - int m_maxProblems; - bool objcp; - TokenIterator m_tokenIt; - -private: - Parser(const Parser& source); - void operator = (const Parser& source); -}; - - -#endif diff -Nru umbrello-4.12.3/umbrello/codeimport/kdevcppparser/position.h umbrello-4.12.90/umbrello/codeimport/kdevcppparser/position.h --- umbrello-4.12.3/umbrello/codeimport/kdevcppparser/position.h 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/codeimport/kdevcppparser/position.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,106 +0,0 @@ -/* - Copyright 2008 Jean Vittor - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of - the License or (at your option) version 3 or any later version - accepted by the membership of KDE e.V. (or its successor approved - by the membership of KDE e.V.), which shall act as a proxy - defined in Section 14 of version 3 of the license. - - 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, see . -*/ -#ifndef POSITION_H -#define POSITION_H - -#include -#include -#include -#include -#include -#include - -typedef boost::spirit::classic::file_position_base PositionType; - -class Position : public PositionType -{ -public: - Position() - { - } - - explicit Position(const QString& fileName) : PositionType(fileName) - { - } - - Position(const Position &p) : PositionType(p) - { - } - - explicit Position(const PositionType &p) : PositionType(p) - { - } - - bool operator<(Position const& p) const - { - assert(file == p.file); - return((line < p.line) || ((line == p.line) && (column < p.column))); - } - - bool operator>=(Position const& p) const - { - return !(*this < p); - } -}; - -inline QDebug operator<<(QDebug out, Position const &p) -{ - out << "Position(" - << "file" << p.file - << "line" << p.line - << "column" << p.column - << ")"; - return out; -} - -typedef boost::spirit::classic::position_iterator CharIteratorType; - -class CharIterator : public CharIteratorType -{ -public: - CharIterator() - { - } - - CharIterator(const QChar *a, const QChar *b, Position p) : CharIteratorType(a,b,p) - { - } - - CharIterator(const PositionType &p) : CharIteratorType(0, 0, p) - { - } -/* - CharIterator(PositionType p) : CharIteratorType(0, 0, p) - { - } -*/ - const Position &get_position() const - { - return static_cast(CharIteratorType::get_position()); - } - - void set_position(Position const& p) - { - CharIteratorType::set_position(p); - } -}; - - -#endif diff -Nru umbrello-4.12.3/umbrello/codeimport/kdevcppparser/preprocesslexer.cpp umbrello-4.12.90/umbrello/codeimport/kdevcppparser/preprocesslexer.cpp --- umbrello-4.12.3/umbrello/codeimport/kdevcppparser/preprocesslexer.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/codeimport/kdevcppparser/preprocesslexer.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,1028 +0,0 @@ -/* - Copyright 2008 Jean Vittor - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "preprocesslexer.h" //was lexer.h - -#include "lookup.h" -#include "keywords.lut.h" -#include "debug_utils.h" - -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "assignFunctor.hpp" - -#define PREPROCESSLEXER_DEBUG - -template -struct identity : public std::unary_function<_Tp,_Tp> { - _Tp& operator()(_Tp& __x) const { return __x; } - const _Tp& operator()(const _Tp& __x) const { return __x; } -}; - -template -struct tilde : public std::unary_function<_Tp, _Tp> { - _Tp operator()(_Tp& __x) const { - return ~__x; - } -}; - -using namespace boost::spirit::classic; -using phoenix::arg1; -using phoenix::arg2; -using phoenix::arg3; -using phoenix::construct_; -using phoenix::function; -using phoenix::var; - -SkipRule PreprocessLexer::m_SkipRule = nothing_p; - -#if defined(KDEVELOP_BGPARSER) -#include - -class KDevTread: public QThread -{ -public: - static void yield() { msleep(0); } -}; - -inline void qthread_yield() -{ - KDevTread::yield(); -} - -#endif - -/** Utility closure that defines a result value. - Used to return values from grammars (copied from cpp lexer in spirit - repository). */ -template < typename ResultT > -struct result_closure : closure, ResultT> { - typedef closure, ResultT> base_t; - typename base_t::member1 result_; -}; - -/** Stuff to construct a QString from iterators */ -struct constructQString_impl { - template - struct result { - typedef QString type; - }; - - template - QString operator()(_Arg1 const& first, _Arg2 const& last) { - return QString(&*first, &*last - &*first); - } -}; - -const function constructQString = constructQString_impl(); - -struct identifier : - grammar::context_t> { - template < typename ScannerT > - struct definition { - typedef rule rule_t; - rule_t main; - - rule_t const& start() const { - return main; - } - - definition(identifier const& self) { - main = (lexeme_d[ - ((alpha_p | '_') >> *(alnum_p | '_')) - [self.result_ = constructQString(arg1, arg2)] - ]); - } - }; -} identifier_pg; - -struct operator_ : - grammar::context_t> { - template < typename ScannerT > - struct definition { - typedef rule::context_t> rule_t; - rule_t main; - - rule_t const& start() const { - return main; - } - - definition(operator_ const& self) { - main = - (str_p("::")[ main.result_ = Token_scope] - | (str_p("->*") | ".*")[ main.result_ = Token_ptrmem] - | (str_p("<<=") | ">>=" | "+=" | "-=" | "*=" | "/=" | "%=" | "^=" | "&=" | "|=")[ main.result_ = Token_assign] - | str_p("<<")[ main.result_ = Token_left_shift] - | (str_p("==") | "!=")[ main.result_ = Token_eq] - | str_p("<=")[ main.result_ = Token_leq] - | str_p(">=")[ main.result_ = Token_geq] - | str_p("&&")[ main.result_ = Token_and] - | str_p("||")[ main.result_ = Token_or] - | str_p("++")[ main.result_ = Token_incr] - | str_p("--")[ main.result_ = Token_decr] - | str_p("->")[ main.result_ = Token_arrow] - | str_p("##")[ main.result_ = Token_concat] - | str_p("...")[ main.result_ = Token_ellipsis] - ) - [ self.result_ = construct_(main.result_, arg1, arg2)]; - } - }; -} operator_pg; - -struct charLiteral : - grammar::context_t> { - template < typename ScannerT > - struct definition { - typedef rule::context_t> rule_t; - rule_t main; - - rule_t const& start() const { - return main; - } - - definition(charLiteral const& self) { - main = - (!ch_p('L') >> ch_p('\'') - >> *((anychar_p - '\'' - '\\') | gr_escapeSequence) - >> '\'') - [ self.result_ = construct_(Token_char_literal, arg1, arg2)]; - } - }; -} charLiteral_pg; - -struct numberLiteral : - grammar::context_t> { - template < typename ScannerT > - struct definition { - typedef rule::context_t> rule_t; - rule_t main; - - rule_t const& start() const { - return main; - } - - definition(numberLiteral const& self) { - main = - (ch_p('0') >> ch_p('x') >> + xdigit_p | + digit_p) - [ self.result_ = construct_(Token_number_literal, arg1, arg2)]; - } - }; -} numberLiteral_pg; - -typedef std::pair Dependency; - -struct DependencyClosure - : boost::spirit::classic::closure { - member1 m_word; - member2 m_scope; -}; - -struct header : - grammar::context_t> { - template < typename ScannerT > - struct definition { - typedef rule rule_t; - rule_t main; - - rule_t const& start() const { - return main; - } - - definition(header const& self) { - main = - (confix_p(ch_p('"')[main.m_scope = (int)Dep_Local], - (*anychar_p)[main.m_word = constructQString(arg1, arg2)], - '"') - | - confix_p(ch_p('<')[main.m_scope = (int)Dep_Global], - (*anychar_p)[main.m_word = constructQString(arg1, arg2)], - '>') - ) - [self.result_ = construct_(main.m_word, main.m_scope)] - ; - } - }; -} header_g; - -extern PreprocessLexer::CharRule gr_stringLiteral; -extern PreprocessLexer::CharRule gr_whiteSpace; -extern PreprocessLexer::CharRule gr_lineComment; -extern PreprocessLexer::CharRule gr_multiLineComment; -extern PreprocessLexer::CharRule gr_skipTillEol; - -Token PreprocessLexer::Source::createToken(int type, CharIterator start, - CharIterator end) const -{ - return Token(type, start, end); -} - -using namespace std; - -struct LexerData { - typedef QMap Scope; - typedef QList StaticChain; - - StaticChain staticChain; - - void beginScope() { - Scope scope; - staticChain.push_front(scope); - } - - void endScope() { - staticChain.pop_front(); - } - - void bind(const QString& name, const QString& value) { - Q_ASSERT(staticChain.size() > 0); - staticChain.front().insert(name, value); - } - - bool hasBind(const QString& name) const { - StaticChain::ConstIterator it = staticChain.begin(); - while (it != staticChain.end()) { - const Scope& scope = *it; - ++it; - - if (scope.contains(name)) - return true; - } - - return false; - } - - QString apply(const QString& name) const { - StaticChain::ConstIterator it = staticChain.begin(); - while (it != staticChain.end()) { - const Scope& scope = *it; - ++it; - - if (scope.contains(name)) - return scope[ name ]; - } - - return QString(); - } - -}; - -PreprocessLexer::PreprocessLexer(Driver* driver) - : m_data(new LexerData), - m_driver(driver), - m_recordComments(false), - m_skipWordsEnabled(true), - m_preprocessorEnabled(true) -{ - reset(); - m_data->beginScope(); -} - -PreprocessLexer::~PreprocessLexer() -{ - m_data->endScope(); - delete m_data; -} - -void PreprocessLexer::setSource(const QString& source, - const QString& p_filename) -{ - reset(); - m_source.set_source(source, p_filename); - m_inPreproc = false; -} - -void PreprocessLexer::reset() -{ - m_preprocessedString.clear(); - m_source.reset(); - m_preprocessor.reset(); -} - -void PreprocessLexer::Preprocessor::reset() -{ - m_skipping.clear(); - m_trueTest.clear(); -} - -// ### should all be done with a "long" type IMO -int PreprocessLexer::toInt(const Token& token) -{ - QString s = token.text(); - if (token.type() == Token_number_literal) { - // hex literal ? - if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) - return s.mid(2).toInt(0, 16); - QString n; - int i = 0; - while (i < int(s.length()) && s[i].isDigit()) - n += s[i++]; - // ### respect more prefixes and suffixes ? - return n.toInt(); - } else if (token.type() == Token_char_literal) { - int i = s[0] == 'L' ? 2 : 1; // wide char ? - if (s[i] == '\\') { - // escaped char - int c = s[i+1].unicode(); - switch (c) { - case '0': - return 0; - case 'r': - return '\r'; - case 'n': - return '\n'; - // ### more - default: - return c; - } - } else { - return s[i].unicode(); - } - } else { - return 0; - } -} - -int PreprocessLexer::evaluateMacro(const QString &token) -{ - if (!m_driver->hasMacro(token)) { - uError() << "undefined macro" << token; - return 0; - } - Macro &m = m_driver->macro(token); - QString value = m.body().trimmed(); - PreprocessLexer lexer(m_driver); - lexer.setSource(value, token); - int result = lexer.macroExpression(); - return result; -} - -void PreprocessLexer::nextLine() -{ - m_source.parse((*gr_whiteSpace) - [boost::bind(&PreprocessLexer::output, this, _1, _2)]); - QChar ch = m_source.currentChar(); - if (ch.isNull() || ch.isSpace()) { - /* skip */ - } else if (m_source.parse(ch_p('#') >> *gr_whiteSpace).hit) { - QString directive; - m_source.parse(identifier_pg[ assign(directive)]); // read the directive - handleDirective(directive); - } else if (m_preprocessor.inSkip()) { - // skip line and continue - m_source.parse(gr_skipTillEol); - return; - } else { - while (!m_source.parse(eol_p).hit) { - Token tk; - nextToken(tk); - if (tk.type() != -1) { - m_preprocessedString += tk.text(); - // TODO: Find a generic way to handle not expanded macros - // which are combined into invalid c code like Q_OBJECTpublic; - if (tk.type() == Token_Q_OBJECT) - m_preprocessedString += QLatin1Char(';'); - } - if (m_source.currentChar().isNull()) - break; - } - } - if (m_source.parse(eol_p).hit) { - m_preprocessedString += '\n'; - } -} - -void PreprocessLexer::nextToken(Token& tk) -{ - m_source.parse((*gr_whiteSpace) - [boost::bind(&PreprocessLexer::output, this, _1, _2)]); - QChar ch = m_source.currentChar(); - if (ch.isNull() || ch.isSpace()) { - // skip - } else if (m_source.parse - ( - if_p(var(m_recordComments)) - [ gr_lineComment | gr_multiLineComment - [var(tk) = construct_(Token_comment, arg1, arg2)] - ] - .else_p[ gr_lineComment | gr_multiLineComment] - | charLiteral_pg[assign(tk)] - | - gr_stringLiteral - [var(tk) = construct_(Token_string_literal, arg1, arg2)] - ).hit) { - } else if (ch.isLetter() || ch == '_') { - CharIterator start = m_source.get_ptr(); - QString ide; - m_source.parse(identifier_pg[assign(ide)]); - int k = Lookup::find(&keyword, ide); - if (m_preprocessorEnabled && m_driver->hasMacro(ide) && - (k == -1 || !m_driver->macro(ide).body().isEmpty())) { - - bool preproc = m_preprocessorEnabled; - m_preprocessorEnabled = false; - - m_data->beginScope(); - - Macro m = m_driver->macro(ide); - - QString ellipsisArg; - - if (m.hasArguments()) { - CharIterator endIde = m_source.get_ptr(); - - m_source.parse(*gr_whiteSpace); - if (m_source.parse(ch_p('(')).hit) { - Macro::ArgumentList::const_iterator l_it = m.arguments().begin(); - Macro::ArgumentList::const_iterator l_last = m.arguments().end(); - while (!m_source.currentChar().isNull() && l_it != l_last) { - m_source.parse(*gr_whiteSpace); - - QString argName = *l_it; - - bool ellipsis = (argName == "..."); - - QString arg = readArgument(); - - if (!ellipsis) - m_data->bind(argName, arg); - else - ellipsisArg += arg; - - if (m_source.parse(ch_p(',')).hit) { - if (!ellipsis) { - ++l_it; - } else { - ellipsisArg += ", "; - } - } else if (m_source.currentChar() == ')') { - break; - } - } - if (m_source.parse(ch_p(')')).hit) { - // valid macro - } - } else { - tk = m_source.createToken(Token_identifier, start, endIde); - - m_data->endScope(); // OPS!! - m_preprocessorEnabled = preproc; - return; - } - } - - Position argsEndAtPosition = currentPosition(); - -#if defined(KDEVELOP_BGPARSER) - qthread_yield(); -#endif - m_preprocessedString += m.body(); - - // tokenize the macro body - - QString textToInsert; - - while (!m_source.currentChar().isNull() - && m_source.currentChar() != '\n' - && m_source.currentChar() != '\r') { - m_source.parse(*gr_whiteSpace); - Token tok; - nextToken(tok); - bool stringify = !m_inPreproc && tok == '#'; - bool merge = !m_inPreproc && tok == Token_concat; - if (stringify || merge) - nextToken(tok); - if (tok == Token_eof) - break; - QString tokText = tok.text(); - QString str = (tok == Token_identifier && m_data->hasBind(tokText)) ? m_data->apply(tokText) : tokText; - if (str == ide) { - m_driver->removeMacro(ide); - } - - if (stringify) { - textToInsert.append(QString::fromLatin1("\"") + str + QString::fromLatin1("\" ")); - } else if (merge) { - textToInsert.truncate(textToInsert.length() - 1); - textToInsert.append(str); - } else if (tok == Token_ellipsis && m_data->hasBind("...")) { - textToInsert.append(ellipsisArg); - } else { - textToInsert.append(str + QString::fromLatin1(" ")); - } - } - -#if defined(KDEVELOP_BGPARSER) - qthread_yield(); -#endif - m_preprocessedString += textToInsert; - - m_data->endScope(); - m_preprocessorEnabled = preproc; - //m_driver->addMacro(m); - m_source.set_currentPosition(argsEndAtPosition); - } else if (k != -1) { - tk = m_source.createToken(k, start); - } else if (m_skipWordsEnabled) { - QMap< QString, QPair >::Iterator pos = m_words.find(ide); - if (pos != m_words.end()) { - if ((*pos).first == SkipWordAndArguments) { - m_source.parse(*gr_whiteSpace); - if (m_source.currentChar() == '(') - skip('(', ')'); - } - if (!(*pos).second.isEmpty()) { -#if defined(KDEVELOP_BGPARSER) - qthread_yield(); -#endif - m_preprocessedString += QString(" ") + (*pos).second + QString(" "); - } - } else if (//qt_rx.exactMatch(ide) || - ide.endsWith(QLatin1String("EXPORT")) || - (ide.startsWith(QLatin1String("Q_EXPORT")) && ide != "Q_EXPORT_INTERFACE") || - ide.startsWith(QLatin1String("QM_EXPORT")) || - ide.startsWith(QLatin1String("QM_TEMPLATE"))) { - - m_source.parse(*gr_whiteSpace); - if (m_source.currentChar() == '(') - skip('(', ')'); - } else if (ide.startsWith(QLatin1String("K_TYPELIST_")) || ide.startsWith(QLatin1String("TYPELIST_"))) { - tk = m_source.createToken(Token_identifier, start); - m_source.parse(*gr_whiteSpace); - if (m_source.currentChar() == '(') - skip('(', ')'); - } else { - tk = m_source.createToken(Token_identifier, start); - } - } else { - tk = m_source.createToken(Token_identifier, start); - } - } else if (m_source.parse(numberLiteral_pg[assign(tk)] - | operator_pg[ assign(tk)] - ).hit) { - } else { - CharIterator l_ptr = m_source.get_ptr(); - m_source.nextChar(); - tk = m_source.createToken(ch.unicode(), l_ptr); - } -} - -void PreprocessLexer::output(CharIterator p_first, CharIterator p_last) -{ - for (; p_first != p_last; ++p_first) - m_preprocessedString += *p_first; -} - -/** - * dump preprocess file to temporay location - */ -void PreprocessLexer::dumpToFile() -{ - QString tempPath = QDir::tempPath() + QString("/umbrello-%1").arg(QCoreApplication::applicationPid()); - QDir d(tempPath); - if (!d.exists()) - d.mkdir(tempPath); - - QString fileName = tempPath + '/' + currentPosition().file.replace(QRegExp("[/:mn]"), "-"); - QFile f(fileName); - if (f.open(QIODevice::WriteOnly | QIODevice::Text)) { - QTextStream out(&f); - out << m_preprocessedString; - } -} - -bool PreprocessLexer::preprocess() -{ - for (;;) { - Position start = currentPosition(); - nextLine(); - if (currentPosition() == start) { -#ifdef PREPROCESSLEXER_DEBUG - dumpToFile(); -#endif - uError() << "preprocess failed" << start; - return false; - } - - if (m_source.currentChar().isNull()) - break; - } - - Token tk = m_source.createToken(Token_eof, m_source.get_ptr()); - m_preprocessedString += tk.text(); - return true; -} - -void PreprocessLexer::addSkipWord(const QString& word, SkipType skipType, const QString& str) -{ - m_words[ word ] = qMakePair(skipType, str); -} - -void PreprocessLexer::skip(int l, int r) -{ - Position svCurrentPosition = currentPosition(); - - int count = 0; - - while (!m_source.eof()) { - Token tk; - nextToken(tk); - - if ((int)tk == l) - ++count; - else if ((int)tk == r) - --count; - - if (count == 0) - break; - } - - m_source.set_currentPosition(svCurrentPosition); -} - -QString PreprocessLexer::readArgument() -{ - int count = 0; - - QString arg; - - m_source.parse(*gr_whiteSpace); - while (!m_source.currentChar().isNull()) { - - m_source.parse(*(gr_whiteSpace | eol_p)); - QChar ch = m_source.currentChar(); - - if (ch.isNull() || (!count && (ch == ',' || ch == ')'))) - break; - - Token tk; - nextToken(tk); - if (tk == '(') { - ++count; - } else if (tk == ')') { - --count; - } - - if (tk != -1) - arg += tk.text() + ' '; - } - - return arg.trimmed(); -} - -void PreprocessLexer::handleDirective(const QString& directive) -{ - m_inPreproc = true; - - bool skip = m_skipWordsEnabled; - bool preproc = m_preprocessorEnabled; - - m_skipWordsEnabled = false; - m_preprocessorEnabled = false; - - if (directive == "define") { - if (!m_preprocessor.inSkip()) - processDefine(); - } else if (directive == "else") { - if (!m_preprocessor.empty()) - m_preprocessor.processElse(); - } else if (directive == "elif") { - if (!m_preprocessor.empty()) - m_preprocessor.processElif(macroExpression()); - } else if (directive == "endif") { - if (!m_preprocessor.empty()) - m_preprocessor.decrement(); - } else if (directive == "if") { - m_preprocessor.processIf(macroExpression()); - } else if (directive == "ifdef") { - m_preprocessor.processIf(macroDefined()); - } else if (directive == "ifndef") { - m_preprocessor.processIf(!macroDefined()); - } else if (directive == "include") { - if (!m_preprocessor.inSkip()) - m_source.parse(*gr_whiteSpace >> - header_g - [boost::bind(&PreprocessLexer::addDependence, this, _1)] - ); - } else if (directive == "undef") { - if (!m_preprocessor.inSkip()) - processUndef(); - } - - // skip line - m_source.parse(gr_skipTillEol); - - m_skipWordsEnabled = skip; - m_preprocessorEnabled = preproc; - - m_inPreproc = false; -} - -bool PreprocessLexer::macroDefined() -{ - QString word; - m_source.parse(*gr_whiteSpace >> identifier_pg[assign(word)]); - return m_driver->hasMacro(word); -} - -struct push_back_c_impl { - template - struct result { - typedef void type; - }; - template - void operator()(Container& c, Item const& item) const { - c.push_back(item); - } -}; - -phoenix::function const push_back_c = push_back_c_impl(); - -struct macroDefinition : - grammar::context_t> { - template < typename ScannerT > - struct definition { - typedef rule rule_t; - rule_t main; - rule_t macroName; - rule::context_t> ellipsis, argument; - - rule_t const& start() const { - return main; - } - - definition(macroDefinition const& self) { - main = - *gr_whiteSpace - >> macroName - >> !(ch_p('(') >> *gr_whiteSpace - >> list_p(*gr_whiteSpace - >> argument[ push_back_c(self.result_, arg1)] - >> *gr_whiteSpace - , - ',' - ) - >> ')'); - macroName = identifier_pg[ self.result_ = construct_(arg1)]; - argument = - ellipsis [assign_a(argument.result_)] - | identifier_pg [assign_a(argument.result_)]; - ellipsis = - str_p("...")[ellipsis.result_ = constructQString(arg1, arg2)]; - } - }; -} macroDefinition_pg; - -void PreprocessLexer::processDefine() -{ - Macro m; - m.setFileName(m_driver->currentFileName()); - m_source.parse(macroDefinition_pg[var(m) = arg1]); - - m_preprocessorEnabled = true; - - QString body; - while (!m_source.currentChar().isNull() - && m_source.currentChar() != '\n' - && m_source.currentChar() != '\r') { - - if (m_source.parse(+ gr_whiteSpace).hit) { - body += ' '; - } else { - Token tk; - nextToken(tk); - - if (tk == '#') { - nextToken(tk); - if (tk.type() != -1) { - body += '"' + tk.text() + '"'; - } - } - else if (tk.type() != -1) { - QString s = tk.text(); - body += s; - } - } - } - - m.setBody(body); - m_driver->removeMacro(m.name()); - m_driver->addMacro(m); -} - -void PreprocessLexer::processUndef() -{ - m_source.parse(*gr_whiteSpace); - QString word; - m_source.parse(identifier_pg[assign(word)]); - m_driver->removeMacro(word); -} - -int PreprocessLexer::macroPrimary() -{ - m_source.parse(*gr_whiteSpace); - int result = 0; - if (m_source.parse(ch_p('(')).hit) { - result = macroExpression(); - bool l_hit = m_source.parse(ch_p(')')).hit; - /** \todo hit must be true */ - if (!l_hit) - result = 0; - } else { - boost::function < int (int) > l_op = identity(); - if (m_source.parse(ch_p('+') - | ch_p('-')[var(l_op) = std::negate()] - | ch_p('!')[var(l_op) = std::logical_not()] - | ch_p('~')[var(l_op) = tilde()] - ).hit) { - result = l_op(macroPrimary()); - } else if (m_source.parse(str_p("defined")).hit) { - /** \todo Strange : should result in an identifier (after - preprocessor variable substitution) ! */ - result = macroPrimary(); - } else { - m_source.parse( - identifier_pg[assignFunctorResult<1> - (result, - boost::bind(&PreprocessLexer::evaluateMacro, boost::ref(*this), _1))] - | numberLiteral_pg[assignFunctorResult<1> - (result, - boost::bind(&PreprocessLexer::toInt, _1))] - | charLiteral_pg[assignFunctorResult<1> - (result, - boost::bind(&PreprocessLexer::toInt, _1))] - ); - } - } - return result; -} - -int PreprocessLexer::macroMultiplyDivide() -{ - int result = macroPrimary(); - int iresult = 0; - int op = 0; - for (;;) { - m_source.parse(*gr_whiteSpace); - if (m_source.parse( - ch_p('*')[var(op) = 0] - | - (ch_p('/') >> eps_p(anychar_p - '*' - '/')) - [var(op) = 1] - | ch_p('%')[var(op) = 2] - ).hit) { - iresult = macroPrimary(); - switch (op) { - case 0: - result = (result * iresult); - break; - case 1: - result = (iresult == 0 ? 0 : (result / iresult)); - break; - case 2: - result = (iresult == 0) ? 0 : (result % iresult); - } - } else - break; - } - return result; -} - -int PreprocessLexer::macroAddSubtract() -{ - int result = macroMultiplyDivide(); - int iresult; - bool ad = false; - m_source.parse(*gr_whiteSpace); - while (m_source.parse( - ch_p('+')[var(ad) = true] | ch_p('-')[var(ad) = false] - ).hit - ) { - iresult = macroMultiplyDivide(); - result = ad ? (result + iresult) : (result - iresult); - } - return result; -} - -int PreprocessLexer::macroRelational() -{ - int result = macroAddSubtract(); - m_source.parse(*gr_whiteSpace); - boost::function < bool (int, int) > l_op; - while (m_source.parse( - str_p("<=")[var(l_op) = less_equal()] - | ch_p('<')[var(l_op) = less()] - | str_p(">=")[var(l_op) = greater_equal()] - | ch_p('>')[var(l_op) = greater()] - ).hit - ) { - int iresult = macroAddSubtract(); - result = l_op(result, iresult); - } - return result; -} - -int PreprocessLexer::macroEquality() -{ - int result = macroRelational(); - m_source.parse(*gr_whiteSpace); - boost::function < bool(int, int) > l_op; - while (m_source.parse(str_p("==")[var(l_op) = equal_to()] - | str_p("!=")[var(l_op) = not_equal_to()] - ).hit) { - result = l_op(result, macroRelational()); - } - return result; -} - -int PreprocessLexer::macroBoolAnd() -{ - int result = macroEquality(); - m_source.parse(*gr_whiteSpace); - while (m_source.parse(ch_p('&') >> eps_p(anychar_p - '&')).hit) - result &= macroEquality(); - return result; -} - -int PreprocessLexer::macroBoolXor() -{ - int result = macroBoolAnd(); - m_source.parse(*gr_whiteSpace); - while (m_source.parse(ch_p('^')).hit) - result ^= macroBoolAnd(); - return result; -} - -int PreprocessLexer::macroBoolOr() -{ - int result = macroBoolXor(); - m_source.parse(*gr_whiteSpace); - while (m_source.parse(ch_p('|') >> eps_p(anychar_p - '|')).hit) - result |= macroBoolXor(); - return result; -} - -int PreprocessLexer::macroLogicalAnd() -{ - int result = macroBoolOr(); - m_source.parse(*gr_whiteSpace); - while (m_source.parse(str_p("&&")).hit) - result = macroBoolOr() && result; - return result; -} - -int PreprocessLexer::macroLogicalOr() -{ - int result = macroLogicalAnd(); - m_source.parse(*gr_whiteSpace); - while (m_source.parse(str_p("||")).hit) - result = macroLogicalAnd() || result; - return result; -} - -int PreprocessLexer::macroExpression() -{ - m_source.parse(*gr_whiteSpace); - return macroLogicalOr(); -} - -PreprocessLexer::CharRule gr_simpleEscapeSequence = (ch_p('\\') >> (ch_p('\\') | '"' | 'a' | 'b' | 'f' | 'n' | 'r' | 't' | 'v' | '0')); -PreprocessLexer::CharRule gr_octalDigit = (ch_p('0') | '1' | '2' | '3' | '4' | '5' | '6' | '7'); -PreprocessLexer::CharRule gr_digit = (ch_p('0') | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'); -PreprocessLexer::CharRule gr_hexDigit = (gr_digit | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'a' | 'b' | 'c' | 'd' | 'e' | 'f'); -PreprocessLexer::CharRule gr_octalEscapeSequence = (ch_p('\\') >> gr_octalDigit >> *gr_octalDigit); -PreprocessLexer::CharRule gr_hexEscapeSequence = (ch_p('\\') >> ch_p('x') >> gr_hexDigit >> gr_hexDigit); -PreprocessLexer::CharRule gr_escapeSequence = gr_simpleEscapeSequence | gr_octalEscapeSequence | gr_hexEscapeSequence; - -// *IMPORTANT* please, don't include preprocesslexer.moc here, because -// PreprocessLexer isn't a QObject class!! if you have problem while -// recompiling try to remove cppsupport/.deps, cppsupport/Makefile.in -// and rerun automake/autoconf - diff -Nru umbrello-4.12.3/umbrello/codeimport/kdevcppparser/preprocesslexer.h umbrello-4.12.90/umbrello/codeimport/kdevcppparser/preprocesslexer.h --- umbrello-4.12.3/umbrello/codeimport/kdevcppparser/preprocesslexer.h 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/codeimport/kdevcppparser/preprocesslexer.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,379 +0,0 @@ -/* This file is part of KDevelop - Copyright (C) 2002, 2003 Roberto Raggi - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef PREPROCESSLEXER_H -#define PREPROCESSLEXER_H - -#include - -namespace boost { namespace spirit { namespace classic { namespace impl { - bool isalnum_(QChar const& c); - bool isalpha_(QChar const& c); - bool isblank_(QChar const& c); - bool isdigit_(QChar const& c); - bool isxdigit_(QChar const& c); -}}}} - -// must be first for msvc (see position.h for more information) -#include "position.h" -#include "driver.h" -#include "skip_rule.hpp" - -#include -#include -#include - -using boost::spirit::classic::parse_info; -using boost::spirit::classic::rule; -using boost::spirit::classic::scanner; -using boost::spirit::classic::ext::skip_rule_parser; - -typedef rule > SkipRule; -typedef skip_rule_parser CharParser; -typedef scanner CharScanner; -typedef CharParser::skip_scanner_policies_t CharPolicies; - -enum SkipType { - SkipWord, - SkipWordAndArguments -}; - -struct LexerData; - -enum Type { - Token_eof = 0, - Token_identifier = 1000, - Token_number_literal, - Token_char_literal, - Token_string_literal, - Token_whitespaces, - Token_comment, - Token_preproc, - - Token_assign = 2000, - Token_ptrmem, - Token_ellipsis, - Token_scope, - Token_left_shift, - Token_eq, - Token_leq, - Token_geq, - Token_incr, - Token_decr, - Token_arrow, - - Token_concat, - - Token_K_DCOP, - Token_k_dcop, - Token_k_dcop_signals, - - Token_Q_OBJECT, - Token_signals, - Token_slots, - Token_emit, - - Token_and, - Token_and_eq, - Token_asm, - Token_auto, - Token_bitand, - Token_bitor, - Token_bool, - Token_break, - Token_case, - Token_catch, - Token_char, - Token_class, - Token_compl, - Token_const, - Token_const_cast, - Token_continue, - Token_default, - Token_delete, - Token_do, - Token_double, - Token_dynamic_cast, - Token_else, - Token_enum, - Token_explicit, - Token_export, - Token_extern, - Token_false, - Token_float, - Token_for, - Token_friend, - Token_goto, - Token_if, - Token_inline, - Token_int, - Token_long, - Token_mutable, - Token_namespace, - Token_new, - Token_not, - Token_not_eq, - Token_operator, - Token_or, - Token_or_eq, - Token_private, - Token_protected, - Token_public, - Token_register, - Token_reinterpret_cast, - Token_return, - Token_short, - Token_signed, - Token_sizeof, - Token_static, - Token_static_cast, - Token_struct, - Token_switch, - Token_template, - Token_this, - Token_throw, - Token_true, - Token_try, - Token_typedef, - Token_typeid, - Token_typename, - Token_union, - Token_unsigned, - Token_using, - Token_virtual, - Token_void, - Token_volatile, - Token_wchar_t, - Token_while, - Token_xor, - Token_xor_eq -}; - -class Token -{ -public: - Token(); - Token(int type, CharIterator start, CharIterator end); - - Token& operator=(Token const& p); - - operator int () const {return m_type;} - - bool isNull() const {return m_type == Token_eof || m_text.isEmpty();} - - int type() const {return m_type;} - - Position const& getStartPosition() const {return m_start;} - Position const& getEndPosition() const {return m_end;} - unsigned int length() const {return m_text.length();} - - QString const& text() const {return m_text;} -private: - int m_type; - Position m_start; - Position m_end; - QString m_text; -}; - -class PreprocessLexer -{ -public: - typedef rule > CharRule; - - explicit PreprocessLexer(Driver* driver); - ~PreprocessLexer(); - - void addSkipWord(const QString& word, SkipType skipType = SkipWord, - const QString& str = QString()); - bool preprocess(); - void setSource(const QString& source, const QString& p_filename); - void setRecordComments(bool record); - QString const& preprocessedString() const {return m_preprocessedString;} -private: - static int toInt(const Token& token); - int evaluateMacro(const QString &token); - void dumpToFile(); - - void addDependence(std::pair const& p_wordAndScope) const { - m_driver->addDependence(m_driver->currentFileName(), - Dependence(p_wordAndScope.first, - p_wordAndScope.second)); - } - - Position currentPosition() const {return m_source.get_currentPosition();} - void nextLine(); - void nextToken(Token& token); - void output(CharIterator p_first, CharIterator p_last); - void skip(int l, int r); - bool recordComments() const; - void reset(); - - // preprocessor (based on an article of Al Stevens on Dr.Dobb's journal) - bool macroDefined(); - QString readArgument(); - - int macroPrimary(); - int macroMultiplyDivide(); - int macroAddSubtract(); - int macroRelational(); - int macroEquality(); - int macroBoolAnd(); - int macroBoolXor(); - int macroBoolOr(); - int macroLogicalAnd(); - int macroLogicalOr(); - int macroExpression(); - - void handleDirective(const QString& directive); - void processDefine(); - void processUndef(); - -private: - static SkipRule m_SkipRule; - - LexerData* m_data; - Driver* m_driver; - QString m_preprocessedString; - - class Source - { - public: - Source() {} - - Token createToken(int type, CharIterator start, CharIterator end) const; - Token createToken(int type, CharIterator start) const { - return createToken(type, start, m_ptr); - } - QChar currentChar() const { - return m_ptr != m_endPtr ? *m_ptr : QChar::Null; - } - bool eof() const {return m_ptr == m_endPtr;} - int length() const {return std::distance(m_ptr, m_endPtr);} - void nextChar() { - QChar l_current = *m_ptr++; - Q_UNUSED(l_current); - } - template - parse_info parse(_RuleT const& p_rule) { - parse_info l_return = - CharParser::parse(m_ptr, m_endPtr, p_rule, m_SkipRule); - if (l_return.hit) - m_ptr = l_return.stop; - return l_return; - } - void reset() { - m_source.clear(); - m_ptr = CharIterator(); - } - void set_source(const QString& source, - const QString& p_filename) { - m_source = source; - m_ptr = CharIterator(m_source.data(), - m_source.data() + m_source.length(), - Position(p_filename)); - } - QString substrFrom(CharIterator start) const { - return QString(&*start, &*m_ptr - &*start); - } - // getters - Position get_currentPosition() const {return m_ptr.get_position();} - CharIterator get_ptr() const {return m_ptr;} - QString const& get_source() const {return m_source;} - // setters - void set_currentPosition(Position const& p) {m_ptr.set_position(p);} - private: - QString m_source; - CharIterator m_ptr; - const CharIterator m_endPtr; - }; - - Source m_source; - bool m_recordComments; - QMap< QString, QPair > m_words; - - bool m_skipWordsEnabled; - - /** Manages skipping. */ - class Preprocessor - { - public: - void decrement() { - m_skipping.pop_back(); - m_trueTest.pop_back(); - } - bool empty() const {return m_skipping.empty();} - bool inSkip() const {return (!empty() && m_skipping.back());} - void processElse() {m_skipping.back() = previousInSkip() || m_trueTest.back();} - void processElif(bool p_test) { - if (m_trueTest.back()) - m_skipping.back() = true; - else { - /// @todo implement the correct semantic for elif!! - m_trueTest.back() = p_test; - m_skipping.back() = previousInSkip() || !p_test; - } - } - void processIf(bool p_test) { - if (increment()) { - m_trueTest.back() = p_test; - m_skipping.back() = inSkip() ? true : !m_trueTest.back(); - } - } - - void reset(); - private: - bool increment() { - bool l_return = false; - if (empty()) - l_return = true; - else - l_return = !m_skipping.back(); - m_skipping.push_back(!l_return); - m_trueTest.push_back(false); - return l_return; - } - bool previousInSkip() const { - return ((m_skipping.size() > 1) && *(++m_skipping.rbegin()));} - - std::vector m_skipping; - std::vector m_trueTest; - }; - - Preprocessor m_preprocessor; - bool m_preprocessorEnabled; - bool m_inPreproc; - -private: - PreprocessLexer(const PreprocessLexer& source); - void operator = (const PreprocessLexer& source); -}; - -inline bool PreprocessLexer::recordComments() const -{ - return m_recordComments; -} - -inline void PreprocessLexer::setRecordComments(bool record) -{ - m_recordComments = record; -} - -extern PreprocessLexer::CharRule gr_escapeSequence; - -#endif diff -Nru umbrello-4.12.3/umbrello/codeimport/kdevcppparser/README umbrello-4.12.90/umbrello/codeimport/kdevcppparser/README --- umbrello-4.12.3/umbrello/codeimport/kdevcppparser/README 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/codeimport/kdevcppparser/README 1970-01-01 00:00:00.000000000 +0000 @@ -1,56 +0,0 @@ -This directory contains the C++ parser from Kdevelop-3.0. - -Following files are copies from the directory kdevelop/lib/cppparser: - ast.{h,cpp} driver.{h,cpp} errors.{h,cpp} keywords.lut.h lexer.{h,cpp} - lookup.{h,cpp} parser.{h,cpp} tree_parser.{h,cpp} - -Following files are copies from the directory kdevelop/languages/cpp: - ast_utils.{h,cpp} - -Following files are copies from the directory kdevelop/lib/util: - urlutil.{h,cpp} - -The source files cpptree2uml.{h,cpp} are based on kdevelop/languages/cpp/ -store_walker.{h,cpp}. The class CppTree2Uml inherits from class TreeParser -and overrides certain methods from that class. - -CppTree2Uml visits the nodes of the abstract syntax tree constructed by the -CppParser, and constructs UML objects on the way. - -The import_utils.h (in the parent directory) is the interface between the -CppTree2Uml and Umbrello. -import_utils implements the construction of the UML objects. CppTree2Uml calls -the create/insert methods in the import_utils while traversing the syntax -tree. - -The one and only method that Umbrello uses for accessing the C++ parser, -and any other parser for that matter, is ClassImport::importFiles(). -The class CppImport (in the parent directory) implements that operation. -Thus we have these classes: - - +-------------------+ - | <> | - | ClassImport | - +===================+ -Umbrello ------>| importFiles() = 0 | - +-------------------+ - A - | <> - | - +-------------------+ +-------------------+ - | CppImport | | CppTree2Uml | - +===================+ <> +===================+ - | importFiles() |-------------->| | - +-------------------+ | | - +-------------------+ - | - +-------------------+ | - | <> | | - | Import_Utils | | - +===================+ | - | createUMLObject() | <> | - | insertMethod() |<-----------------------+ - | insertAttribute() | - +-------------------+ - | -Umbrello <--------------+ diff -Nru umbrello-4.12.3/umbrello/codeimport/kdevcppparser/skip_rule.hpp umbrello-4.12.90/umbrello/codeimport/kdevcppparser/skip_rule.hpp --- umbrello-4.12.3/umbrello/codeimport/kdevcppparser/skip_rule.hpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/codeimport/kdevcppparser/skip_rule.hpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,99 +0,0 @@ -#ifndef SKIP_RULE_H -#define SKIP_RULE_H - -#include - -/** This header should (hopefully) be part of a future release of - boost::spirit */ - -namespace boost { -namespace spirit { -namespace classic { -namespace ext { - -template < typename RuleT, typename BaseT = iteration_policy > -class skip_rule_iteration_policy - : public skipper_iteration_policy -{ -public: - - typedef skipper_iteration_policy base_t; - typedef typename RuleT::scanner_t skip_rule_scanner_t; - typedef typename skip_rule_scanner_t::policies_t skip_rule_policies_t; - - skip_rule_iteration_policy(RuleT const& skip_rule, - skip_rule_policies_t const& policies - = skip_rule_policies_t(), - base_t const& base = base_t()) - : base_t(base), subject(skip_rule), _policies(policies) {} - - template - skip_rule_iteration_policy(PolicyT const& other) - : base_t(other), subject(other.skipper()), - _policies(other.policies()) {} - - template - void skip(ScannerT const& scan) const { - skip_rule_scanner_t skip_scanner(scan.first, scan.last, _policies); - impl::skipper_skip(subject, skip_scanner, skip_scanner); - } - - RuleT const& skipper() const { - return subject; - } - - skip_rule_policies_t const& policies() const { - return _policies; - } - -private: - RuleT const& subject; - skip_rule_policies_t const& _policies; -}; - -template < typename SkipRuleT -, typename IteratorT = char const* -, typename SkipMatchPolicyT = match_policy -, typename SkipActionPolicyT = action_policy > -struct skip_rule_parser { - typedef IteratorT iterator_t; - typedef SkipRuleT skip_rule_t; - typedef - typename skip_rule_t::scanner_t::policies_t skip_rule_policies_t; - typedef skip_rule_iteration_policy skip_iteration_policy_t; - typedef SkipMatchPolicyT skip_match_policy_t; - typedef SkipActionPolicyT skip_action_policy_t; - typedef scanner_policies < - skip_iteration_policy_t - , skip_match_policy_t - , skip_action_policy_t > - skip_scanner_policies_t; - typedef scanner - skip_scanner_t; - - template - static parse_info - parse(iterator_t const& first_, - iterator_t const& last, - parser const& p, - skip_rule_t const& skip, - skip_match_policy_t const& smp = match_policy(), - skip_action_policy_t const& sap = action_policy(), - skip_rule_policies_t const& srps = skip_rule_policies_t()) { - skip_iteration_policy_t sip(skip, srps); - skip_scanner_policies_t policies(sip, smp, sap); - iterator_t first = first_; - skip_scanner_t scan(first, last, policies); - match hit = p.derived().parse(scan); - scan.skip(scan); - return parse_info - (first, hit, hit && (first == last), hit.length()); - } -}; - -} // end namespace ext -} // end namespace classic -} // end namespace spirit -} // end namespace boost - -#endif diff -Nru umbrello-4.12.3/umbrello/codeimport/kdevcppparser/tree_parser.cpp umbrello-4.12.90/umbrello/codeimport/kdevcppparser/tree_parser.cpp --- umbrello-4.12.3/umbrello/codeimport/kdevcppparser/tree_parser.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/codeimport/kdevcppparser/tree_parser.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,214 +0,0 @@ -/* This file is part of KDevelop - Copyright (C) 2002, 2003 Roberto Raggi - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "tree_parser.h" - -#include "debug_utils.h" - -#include - -TreeParser::TreeParser() -{ -} - -TreeParser::~TreeParser() -{ -} - -void TreeParser::parseTranslationUnit(TranslationUnitAST* translationUnit) -{ - QList declarations = translationUnit->declarationList(); - for(int i = 0; i < declarations.size(); ++i) { - parseDeclaration(declarations.at(i)); - } -} - -void TreeParser::parseDeclaration(DeclarationAST* declaration) -{ - //uDebug() << "TreeParser::parseDeclaration()"; - - if (!declaration) - return; - - switch (declaration->nodeType()) { - case NodeType_File: - parseFile(static_cast(declaration)); - break; - - case NodeType_LinkageSpecification: - parseLinkageSpecification(static_cast(declaration)); - break; - - case NodeType_Namespace: - parseNamespace(static_cast(declaration)); - break; - - case NodeType_NamespaceAlias: - parseNamespaceAlias(static_cast(declaration)); - break; - - case NodeType_Using: - parseUsing(static_cast(declaration)); - break; - - case NodeType_UsingDirective: - parseUsingDirective(static_cast(declaration)); - break; - - case NodeType_Typedef: - parseTypedef(static_cast(declaration)); - break; - - case NodeType_TemplateDeclaration: - parseTemplateDeclaration(static_cast(declaration)); - break; - - case NodeType_SimpleDeclaration: - parseSimpleDeclaration(static_cast(declaration)); - break; - - case NodeType_FunctionDefinition: - parseFunctionDefinition(static_cast(declaration)); - break; - - case NodeType_AccessDeclaration: - parseAccessDeclaration(static_cast(declaration)); - break; - } -} - -void TreeParser::parseFile(FileAST* decl) -{ - //uDebug() << "TreeParser::parseFile()"; - Q_UNUSED(decl); -} - -void TreeParser::parseLinkageSpecification(LinkageSpecificationAST* ast) -{ - //uDebug() << "TreeParser::parseLinkageSpecification()"; - if (ast->linkageBody()) - parseLinkageBody(ast->linkageBody()); - else if (ast->declaration()) - parseDeclaration(ast->declaration()); -} - -void TreeParser::parseNamespace(NamespaceAST* decl) -{ - //uDebug() << "TreeParser::parseNamespace()"; - if (decl->linkageBody()) - parseLinkageBody(decl->linkageBody()); -} - -void TreeParser::parseNamespaceAlias(NamespaceAliasAST* decl) -{ - //uDebug() << "TreeParser::parseNamespaceAlias()"; - Q_UNUSED(decl); -} - -void TreeParser::parseUsing(UsingAST* decl) -{ - //uDebug() << "TreeParser::parseUsing()"; - Q_UNUSED(decl); -} - -void TreeParser::parseUsingDirective(UsingDirectiveAST* decl) -{ - //uDebug() << "TreeParser::parseUsingDirective()"; - Q_UNUSED(decl); -} - -void TreeParser::parseTypedef(TypedefAST* decl) -{ - //uDebug() << "TreeParser::parseTypedef()"; - if (decl->typeSpec()) - parseTypeSpecifier(decl->typeSpec()); -} - -void TreeParser::parseTemplateDeclaration(TemplateDeclarationAST* decl) -{ - //uDebug() << "TreeParser::parseTemplateDeclaration()"; - Q_UNUSED(decl); -} - -void TreeParser::parseSimpleDeclaration(SimpleDeclarationAST* decl) -{ - //uDebug() << "TreeParser::parseSimpleDeclaration()"; - Q_UNUSED(decl); -} - -void TreeParser::parseFunctionDefinition(FunctionDefinitionAST* def) -{ - //uDebug() << "TreeParser::parseFunctionDefinition()"; - Q_UNUSED(def); -} - -void TreeParser::parseLinkageBody(LinkageBodyAST* linkageBody) -{ - //uDebug() << "TreeParser::parseLinkageBody()"; - QList declarations = linkageBody->declarationList(); - for(int i = 0; i < declarations.size(); ++i) { - parseDeclaration(declarations.at(i)); - } -} - -void TreeParser::parseTypeSpecifier(TypeSpecifierAST* typeSpec) -{ - //uDebug() << "TreeParser::parseTypeSpecifier()"; - switch (typeSpec->nodeType()) { - case NodeType_ClassSpecifier: - parseClassSpecifier(static_cast(typeSpec)); - break; - - case NodeType_EnumSpecifier: - parseEnumSpecifier(static_cast(typeSpec)); - break; - - case NodeType_ElaboratedTypeSpecifier: - parseElaboratedTypeSpecifier(static_cast(typeSpec)); - break; - } -} - -void TreeParser::parseClassSpecifier(ClassSpecifierAST* classSpec) -{ - //uDebug() << "TreeParser::parseClassSpecifier()"; - QList declarations = classSpec->declarationList(); - for(int i = 0; i < declarations.size(); ++i) { - parseDeclaration(declarations.at(i)); - } -} - -void TreeParser::parseEnumSpecifier(EnumSpecifierAST* enumSpec) -{ - //uDebug() << "TreeParser::parseEnumSpecifier()"; - Q_UNUSED(enumSpec); -} - -void TreeParser::parseElaboratedTypeSpecifier(ElaboratedTypeSpecifierAST* typeSpec) -{ - //uDebug() << "TreeParser::parseElaboratedTypeSpecifier()"; - Q_UNUSED(typeSpec); -} - -void TreeParser::parseAccessDeclaration(AccessDeclarationAST * access) -{ - //uDebug() << "TreeParser::parseAccessDeclaration()"; - Q_UNUSED(access); -} - diff -Nru umbrello-4.12.3/umbrello/codeimport/kdevcppparser/tree_parser.h umbrello-4.12.90/umbrello/codeimport/kdevcppparser/tree_parser.h --- umbrello-4.12.3/umbrello/codeimport/kdevcppparser/tree_parser.h 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/codeimport/kdevcppparser/tree_parser.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,60 +0,0 @@ -/* This file is part of KDevelop - Copyright (C) 2002, 2003 Roberto Raggi - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef TREE_PARSER_H -#define TREE_PARSER_H - -#include "ast.h" - -class TreeParser -{ -public: - TreeParser(); - virtual ~TreeParser(); - - // translation-unit - virtual void parseTranslationUnit(TranslationUnitAST*); - - // declarations - virtual void parseDeclaration(DeclarationAST*); - virtual void parseFile(FileAST*); - virtual void parseLinkageSpecification(LinkageSpecificationAST*); - virtual void parseNamespace(NamespaceAST*); - virtual void parseNamespaceAlias(NamespaceAliasAST*); - virtual void parseUsing(UsingAST*); - virtual void parseUsingDirective(UsingDirectiveAST*); - virtual void parseTypedef(TypedefAST*); - virtual void parseTemplateDeclaration(TemplateDeclarationAST*); - virtual void parseSimpleDeclaration(SimpleDeclarationAST*); - virtual void parseFunctionDefinition(FunctionDefinitionAST*); - virtual void parseLinkageBody(LinkageBodyAST*); - virtual void parseAccessDeclaration(AccessDeclarationAST*); - - // type-specifier - virtual void parseTypeSpecifier(TypeSpecifierAST*); - virtual void parseClassSpecifier(ClassSpecifierAST*); - virtual void parseEnumSpecifier(EnumSpecifierAST*); - virtual void parseElaboratedTypeSpecifier(ElaboratedTypeSpecifierAST*); - -private: - TreeParser(const TreeParser& source); - void operator = (const TreeParser& source); -}; - -#endif // TREE_PARSER_H diff -Nru umbrello-4.12.3/umbrello/codeimpwizard/codeimpselectpage.cpp umbrello-4.12.90/umbrello/codeimpwizard/codeimpselectpage.cpp --- umbrello-4.12.3/umbrello/codeimpwizard/codeimpselectpage.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/codeimpwizard/codeimpselectpage.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -55,6 +55,7 @@ setupTreeView(); connect(ui_treeView, SIGNAL(clicked(QModelIndex)), this, SLOT(treeClicked(QModelIndex))); + connect(ui_treeView, SIGNAL(entered(QModelIndex)), this, SLOT(treeEntered(QModelIndex))); setupFileExtEdit(); connect(ui_fileExtLineEdit, SIGNAL(editingFinished()), this, SLOT(fileExtChanged())); @@ -107,7 +108,11 @@ ui_treeView->setModel(model); ui_treeView->setIndentation(20); ui_treeView->setColumnWidth(0, 200); + ui_treeView->setSortingEnabled(true); + ui_treeView->header() + ->setSortIndicator(0, Qt::AscendingOrder); + ui_treeView->setWindowTitle(i18n("File System Model")); if (s_recentPath.isEmpty()) { ui_treeView->setCurrentIndex(model->index(QDir::currentPath())); @@ -115,6 +120,8 @@ else { ui_treeView->setCurrentIndex(model->index(s_recentPath)); } + ui_treeView->scrollTo(ui_treeView->currentIndex()); + ui_treeView->setMouseTracking(true); ui_treeView->show(); } @@ -272,6 +279,12 @@ } } +void CodeImpSelectPage::treeEntered(const QModelIndex &index) +{ + Q_UNUSED(index); + ui_treeView->resizeColumnToContents(0); +} + /** * Reimplemented QWizardPage method to validate page when user clicks next button. * @return the validation state diff -Nru umbrello-4.12.3/umbrello/codeimpwizard/codeimpselectpage.h umbrello-4.12.90/umbrello/codeimpwizard/codeimpselectpage.h --- umbrello-4.12.3/umbrello/codeimpwizard/codeimpselectpage.h 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/codeimpwizard/codeimpselectpage.h 2014-03-05 15:04:09.000000000 +0000 @@ -60,6 +60,7 @@ protected slots: void languageChanged(int id); void treeClicked(const QModelIndex& index); + void treeEntered(const QModelIndex& index); private slots: void changeLanguage(); diff -Nru umbrello-4.12.3/umbrello/codeimpwizard/codeimpselectpage.ui umbrello-4.12.90/umbrello/codeimpwizard/codeimpselectpage.ui --- umbrello-4.12.3/umbrello/codeimpwizard/codeimpselectpage.ui 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/codeimpwizard/codeimpselectpage.ui 2014-03-05 15:04:09.000000000 +0000 @@ -74,7 +74,7 @@ - List of file extensions + List of file extensions: diff -Nru umbrello-4.12.3/umbrello/debug/debug_utils.cpp umbrello-4.12.90/umbrello/debug/debug_utils.cpp --- umbrello-4.12.3/umbrello/debug/debug_utils.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/debug/debug_utils.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -49,7 +49,6 @@ setAlternatingRowColors(true); setHeaderLabel(i18n("Class Name")); setContextMenuPolicy(Qt::CustomContextMenu); - resize(300, 400); connect(this, SIGNAL(itemClicked(QTreeWidgetItem*,int)), this, SLOT(slotItemClicked(QTreeWidgetItem*,int))); } diff -Nru umbrello-4.12.3/umbrello/debug/debug_utils.h umbrello-4.12.90/umbrello/debug/debug_utils.h --- umbrello-4.12.3/umbrello/debug/debug_utils.h 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/debug/debug_utils.h 2014-03-05 15:04:09.000000000 +0000 @@ -99,6 +99,7 @@ #define DBG_SRC QString(metaObject()->className()) #define DEBUG_SHOW_FILTER() Tracer::instance()->show() #define DEBUG(src) if (Tracer::instance()->isEnabled(src)) uDebug() +#define IS_DEBUG_ENABLED(src) Tracer::instance()->isEnabled(src) #define DEBUG_REGISTER(src) class src##Tracer { public: src##Tracer() { Tracer::registerClass(#src, true); } }; static src##Tracer src##TracerGlobal; #define DEBUG_REGISTER_DISABLED(src) class src##Tracer { public: src##Tracer() { Tracer::registerClass(#src, false); } }; static src##Tracer src##TracerGlobal; diff -Nru umbrello-4.12.3/umbrello/dialogs/classifierlistpage.cpp umbrello-4.12.90/umbrello/dialogs/classifierlistpage.cpp --- umbrello-4.12.3/umbrello/dialogs/classifierlistpage.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/dialogs/classifierlistpage.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -482,7 +482,7 @@ return; UMLClassifierListItem* listItem = getItemList().at(currentItemIndex); if (!listItem && id != ListPopupMenu::mt_New_Attribute) { - uDebug() << "can not find att from selection"; + uDebug() << "cannot find att from selection"; return; } m_bSigWaiting = true; @@ -671,7 +671,7 @@ UMLClassifierListItem* listItem = getItemList().at(m_pItemListLB->row(item)); if (!listItem) { - uDebug() << "can not find att from selection"; + uDebug() << "cannot find att from selection"; return; } diff -Nru umbrello-4.12.3/umbrello/dialogs/classoptionspage.cpp umbrello-4.12.90/umbrello/dialogs/classoptionspage.cpp --- umbrello-4.12.3/umbrello/dialogs/classoptionspage.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/dialogs/classoptionspage.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -12,6 +12,7 @@ #include "classoptionspage.h" // local includes +#include "umlscene.h" #include "umlview.h" #include "classifierwidget.h" #include "widgetbase.h" @@ -31,7 +32,8 @@ * Constructor - observe and modify a Widget */ ClassOptionsPage::ClassOptionsPage(QWidget* pParent, ClassifierWidget* pWidget) - : QWidget(pParent) + : QWidget(pParent), + m_isDiagram(false) { init(); //WidgetType type = pWidget->baseType(); @@ -39,6 +41,15 @@ setupPage(); } +ClassOptionsPage::ClassOptionsPage(QWidget *pParent, UMLScene *scene) + : QWidget(pParent), + m_isDiagram(false) +{ + init(); + m_scene = scene; + setupPageFromScene(); +} + /** * Constructor - observe and modify an OptionState structure * @@ -84,6 +95,8 @@ applyWidget(); } else if (m_options) { applyOptionState(); + } else if (m_scene) { + applyScene(); } } @@ -168,6 +181,25 @@ } } +void ClassOptionsPage::setupPageFromScene() +{ + int margin = fontMetrics().height(); + + QVBoxLayout * topLayout = new QVBoxLayout(this); + + topLayout->setSpacing(6); + m_visibilityGB = new QGroupBox(i18n("Show"), this); + topLayout->addWidget(m_visibilityGB); + QGridLayout * visibilityLayout = new QGridLayout(m_visibilityGB); + visibilityLayout->setSpacing(10); + visibilityLayout->setMargin(margin); + visibilityLayout->setRowStretch(3, 1); + + m_showOpSigCB = new QCheckBox(i18n("O&peration signature"), m_visibilityGB); + m_showOpSigCB->setChecked(m_scene->showOpSig()); + visibilityLayout->addWidget(m_showOpSigCB, 1, 0); +} + /** * Creates the page based on the OptionState */ @@ -297,10 +329,19 @@ } /** + * Sets the UMLScene's properties to those selected in this dialog page. + */ +void ClassOptionsPage::applyScene() +{ + m_scene->setShowOpSig(m_showOpSigCB->isChecked()); +} + +/** * Initialize optional items */ void ClassOptionsPage::init() { + m_scene = NULL; m_options = NULL; m_pWidget = NULL; m_showStereotypeCB = NULL; diff -Nru umbrello-4.12.3/umbrello/dialogs/classoptionspage.h umbrello-4.12.90/umbrello/dialogs/classoptionspage.h --- umbrello-4.12.3/umbrello/dialogs/classoptionspage.h 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/dialogs/classoptionspage.h 2014-03-05 15:04:09.000000000 +0000 @@ -17,6 +17,7 @@ #include class ClassifierWidget; +class UMLScene; class KComboBox; class QCheckBox; class QGroupBox; @@ -38,6 +39,7 @@ { public: ClassOptionsPage(QWidget* pParent, ClassifierWidget* pWidget); + ClassOptionsPage(QWidget* pParent, UMLScene *scene); ClassOptionsPage(QWidget* pParent, Settings::OptionState *options, bool isDiagram=true); virtual ~ClassOptionsPage(); @@ -50,10 +52,12 @@ void init(); void setupPage(); + void setupPageFromScene(); void setupClassPageOption(); void applyWidget(); void applyOptionState(); + void applyScene(); void insertAttribScope(const QString& type, int index = -1); void insertOperationScope(const QString& type, int index = -1); @@ -73,6 +77,7 @@ KComboBox * m_operationScopeCB; ClassifierWidget* m_pWidget; ///< The classifier widget to represent in the dialog page. + UMLScene* m_scene; ///< The scene to represent in the dialog page. Settings::OptionState *m_options; ///< The OptionState structure to represent in the dialog page. bool m_isDiagram; ///< Flag indicating that page is for diagram property dialog }; diff -Nru umbrello-4.12.3/umbrello/dialogs/codeeditor.cpp umbrello-4.12.90/umbrello/dialogs/codeeditor.cpp --- umbrello-4.12.3/umbrello/dialogs/codeeditor.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/dialogs/codeeditor.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -876,7 +876,7 @@ else if (dynamic_cast(m_selectedTextBlock)) m_textBlockToPaste = CodeGenFactory::newCodeComment(m_parentDoc); else { - uError() << " ERROR: CodeEditor can not copy selected block:" << m_selectedTextBlock << " of unknown type"; + uError() << " ERROR: CodeEditor cannot copy selected block:" << m_selectedTextBlock << " of unknown type"; m_textBlockToPaste = 0; return; // error! } diff -Nru umbrello-4.12.3/umbrello/dialogs/diagrampropertiespage.cpp umbrello-4.12.90/umbrello/dialogs/diagrampropertiespage.cpp --- umbrello-4.12.3/umbrello/dialogs/diagrampropertiespage.cpp 1970-01-01 00:00:00.000000000 +0000 +++ umbrello-4.12.90/umbrello/dialogs/diagrampropertiespage.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -0,0 +1,115 @@ +/*************************************************************************** + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * copyright (C) 2002-2014 * + * Umbrello UML Modeller Authors * + ***************************************************************************/ + +// own header +#include "diagrampropertiespage.h" + +// local includes +#include "uml.h" +#include "umldoc.h" +#include "umlscene.h" +#include "umlview.h" + +// kde includes +#include + +// qt includes + +/** + * Constructor + * @param parent the parent (wizard) of this wizard page + */ +DiagramPropertiesPage::DiagramPropertiesPage(QWidget *parent, UMLScene *scene) + : QWidget(parent), m_scene(scene) +{ + setupUi(this); + + ui_diagramName->setText(scene->name()); + ui_zoom->setValue(scene->activeView()->currentZoom()); + + ui_checkBoxShowGrid->setChecked(scene->isSnapGridVisible()); + ui_snapToGrid->setChecked(scene->snapToGrid()); + ui_snapComponentSizeToGrid->setChecked(scene->snapComponentSizeToGrid()); + + ui_gridSpaceX->setValue(scene->snapX()); + ui_gridSpaceY->setValue(scene->snapY()); + ui_documentation->setText(scene->documentation()); + if (scene->type() == Uml::DiagramType::Sequence) { + ui_autoIncrementSequence->setVisible(true); + ui_autoIncrementSequence->setChecked(scene->autoIncrementSequence()); + } else { + ui_autoIncrementSequence->setVisible(false); + } +} + +/** + * destructor + */ +DiagramPropertiesPage::~DiagramPropertiesPage() +{ +} + +/** + * sets default values + */ +void DiagramPropertiesPage::setDefaults() +{ +} + +/** + Checks whether the diagram name is unique and sets it if it is. +*/ +bool DiagramPropertiesPage::checkUniqueDiagramName() +{ + // check name + QString newName = ui_diagramName->text(); + if (newName.length() == 0) { + KMessageBox::sorry(this, i18n("The name you have entered is invalid."), + i18n("Invalid Name"), 0); + ui_diagramName->setText(m_scene->name()); + return false; + } + + if (newName != m_scene->name()) { + UMLDoc* doc = UMLApp::app()->document(); + UMLView* view = doc->findView(m_scene->type(), newName); + if (view) { + KMessageBox::sorry(this, i18n("The name you have entered is not unique."), + i18n("Name Not Unique"), 0); + ui_diagramName->setText(m_scene->name()); + } + else { + // uDebug() << "Cannot find view with name " << newName; + m_scene->setName(newName); + doc->signalDiagramRenamed(m_scene->activeView()); + return true; + } + } + return false; +} + +/** + * Reads the set values from their corresponding widgets, writes them back to + * the data structure, and notifies clients. + */ +void DiagramPropertiesPage::apply() +{ + checkUniqueDiagramName(); + //:TODO: m_pScene->setZoom(m_diagramProperties->ui_zoom->value()); + m_scene->setDocumentation(ui_documentation->toPlainText()); + m_scene->setSnapSpacing(ui_gridSpaceX->value(), ui_gridSpaceY->value()); + m_scene->setSnapToGrid(ui_snapToGrid->isChecked()); + m_scene->setSnapComponentSizeToGrid(ui_snapComponentSizeToGrid->isChecked()); + m_scene->setSnapGridVisible(ui_checkBoxShowGrid->isChecked()); + if (m_scene->type() == Uml::DiagramType::Sequence) { + m_scene->setAutoIncrementSequence(ui_autoIncrementSequence->isChecked()); + } + emit applyClicked(); +} diff -Nru umbrello-4.12.3/umbrello/dialogs/diagrampropertiespage.h umbrello-4.12.90/umbrello/dialogs/diagrampropertiespage.h --- umbrello-4.12.3/umbrello/dialogs/diagrampropertiespage.h 1970-01-01 00:00:00.000000000 +0000 +++ umbrello-4.12.90/umbrello/dialogs/diagrampropertiespage.h 2014-03-05 15:04:09.000000000 +0000 @@ -0,0 +1,40 @@ +/*************************************************************************** + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * copyright (C) 2002-2014 * + * Umbrello UML Modeller Authors * + ***************************************************************************/ + +#ifndef DIAGRAMPROPERTIESPAGE_H +#define DIAGRAMPROPERTIESPAGE_H + +#include "ui_diagrampropertiespage.h" + +#include + +class UMLScene; + +/** + * A dialog page to display diagram properties + */ +class DiagramPropertiesPage : public QWidget, public Ui::DiagramPropertiesPage +{ + Q_OBJECT +public: + explicit DiagramPropertiesPage(QWidget *parent, UMLScene *scene); + virtual ~DiagramPropertiesPage(); + + void setDefaults(); + void apply(); + +signals: + void applyClicked(); + +protected: + UMLScene *m_scene; + bool checkUniqueDiagramName(); +}; +#endif diff -Nru umbrello-4.12.3/umbrello/dialogs/diagrampropertiespage.ui umbrello-4.12.90/umbrello/dialogs/diagrampropertiespage.ui --- umbrello-4.12.3/umbrello/dialogs/diagrampropertiespage.ui 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/dialogs/diagrampropertiespage.ui 2014-03-05 15:04:09.000000000 +0000 @@ -86,15 +86,21 @@ + + + + Qt::Horizontal + + + + 40 + 20 + + + + - - - - Show operation signature - - - @@ -158,6 +164,19 @@ + + + Qt::Horizontal + + + + 40 + 20 + + + + + X diff -Nru umbrello-4.12.3/umbrello/dialogs/selectopdlg.cpp umbrello-4.12.90/umbrello/dialogs/selectopdlg.cpp --- umbrello-4.12.3/umbrello/dialogs/selectopdlg.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/dialogs/selectopdlg.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -72,6 +72,7 @@ m_pOpAS = new QCheckBox(i18n("Auto increment:"), m_pOpGB); mainLayout->addWidget(m_pOpAS, 0, 2); + connect(m_pOpAS, SIGNAL(toggled(bool)), this, SLOT(slotAutoIncrementChecked(bool))); m_pOpRB = new QLabel(i18n("Class operation:"), m_pOpGB); mainLayout->addWidget(m_pOpRB, 1, 0); @@ -82,7 +83,7 @@ connect(m_pOpCB, SIGNAL(currentIndexChanged(int)), this, SLOT(slotIndexChanged(int))); mainLayout->addWidget(m_pOpCB, 1, 1, 1, 2); - m_newOperationButton = new QPushButton(i18n("New"), m_pOpGB); + m_newOperationButton = new QPushButton(i18n("New Operation..."), m_pOpGB); connect(m_newOperationButton, SIGNAL(clicked()), this, SLOT(slotNewOperation())); mainLayout->addWidget(m_newOperationButton, 1, 3); @@ -139,6 +140,15 @@ } /** + * handle auto increment checkbox click + */ +void SelectOpDlg::slotAutoIncrementChecked(bool state) +{ + if (state && m_pSeqLE->text().isEmpty()) + m_pSeqLE->setText(QLatin1String("1")); +} + +/** * handle new operation button click */ void SelectOpDlg::slotNewOperation() @@ -197,6 +207,8 @@ { m_pOpCB->clear(); UMLOperationList list = m_classifier->getOpList(true); + if (list.count() > 0) + m_pOpCB->insertItem(0, ""); qSort(list.begin(), list.end(), caseInsensitiveLessThan); foreach(UMLOperation * obj, list) { QString s = obj->toString(Uml::SignatureType::SigNoVis); diff -Nru umbrello-4.12.3/umbrello/dialogs/selectopdlg.h umbrello-4.12.90/umbrello/dialogs/selectopdlg.h --- umbrello-4.12.3/umbrello/dialogs/selectopdlg.h 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/dialogs/selectopdlg.h 2014-03-05 15:04:09.000000000 +0000 @@ -72,6 +72,7 @@ UMLClassifier *m_classifier; public slots: + void slotAutoIncrementChecked(bool state); void slotNewOperation(); void slotIndexChanged(int index); void slotTextChanged(const QString &text); diff -Nru umbrello-4.12.3/umbrello/dialogs/umlviewdialog.cpp umbrello-4.12.90/umbrello/dialogs/umlviewdialog.cpp --- umbrello-4.12.3/umbrello/dialogs/umlviewdialog.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/dialogs/umlviewdialog.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -13,6 +13,7 @@ // local includes #include "classoptionspage.h" +#include "diagrampropertiespage.h" #include "debug_utils.h" #include "icon_utils.h" #include "uml.h" @@ -59,7 +60,7 @@ void UMLViewDialog::slotOk() { - applyPage(m_pageGeneralItem); + applyPage(m_pageDiagramItem); applyPage(m_pageDisplayItem); applyPage(m_pageFontItem); applyPage(m_pageStyleItem); @@ -79,7 +80,7 @@ setupDiagramPropertiesPage(); setupStylePage(); setupFontPage(); - setupClassPage(); + setupDisplayPage(); } /** @@ -88,41 +89,28 @@ void UMLViewDialog::setupDiagramPropertiesPage() { KVBox *page = new KVBox(); - m_pageGeneralItem = new KPageWidgetItem(page, i18nc("general settings page", "General")); - m_pageGeneralItem->setHeader(i18n("General Settings")); - m_pageGeneralItem->setIcon(Icon_Utils::DesktopIcon(Icon_Utils::it_Properties_General)); - addPage(m_pageGeneralItem); + m_pageDiagramItem = new KPageWidgetItem(page, i18nc("general settings page", "General")); + m_pageDiagramItem->setHeader(i18n("General Settings")); + m_pageDiagramItem->setIcon(Icon_Utils::DesktopIcon(Icon_Utils::it_Properties_General)); + addPage(m_pageDiagramItem); - m_diagramProperties = new DiagramPropertiesPage(page); - - m_diagramProperties->ui_diagramName->setText(m_pScene->name()); - m_diagramProperties->ui_zoom->setValue(m_pScene->activeView()->currentZoom()); - m_diagramProperties->ui_showOpSigs->setChecked(m_pScene->showOpSig()); - - m_diagramProperties->ui_checkBoxShowGrid->setChecked(m_pScene->isSnapGridVisible()); - m_diagramProperties->ui_snapToGrid->setChecked(m_pScene->snapToGrid()); - m_diagramProperties->ui_snapComponentSizeToGrid->setChecked(m_pScene->snapComponentSizeToGrid()); - - m_diagramProperties->ui_gridSpaceX->setValue(m_pScene->snapX()); - m_diagramProperties->ui_gridSpaceY->setValue(m_pScene->snapY()); - m_diagramProperties->ui_lineWidth->setValue(m_pScene->lineWidth()); - m_diagramProperties->ui_documentation->setText(m_pScene->documentation()); - if (m_pScene->type() == Uml::DiagramType::Sequence) { - m_diagramProperties->ui_autoIncrementSequence->setVisible(true); - m_diagramProperties->ui_autoIncrementSequence->setChecked(m_pScene->autoIncrementSequence()); - } else { - m_diagramProperties->ui_autoIncrementSequence->setVisible(false); - } + m_diagramPropertiesPage = new DiagramPropertiesPage(page, m_pScene); } /** - * Sets up the Class page + * Sets up the display page */ -void UMLViewDialog::setupClassPage() +void UMLViewDialog::setupDisplayPage() { - if (m_pScene->type() != Uml::DiagramType::Class) { + m_pageDisplayItem = 0; + // Display page currently only shows class-related display options that are + // applicable for class- and sequence diagram + if (m_pScene->type() != Uml::DiagramType::Class && + m_pScene->type() != Uml::DiagramType::Sequence) { return; } + + QFrame * newPage = new QFrame(); m_pageDisplayItem = new KPageWidgetItem(newPage, i18nc("classes display options page", "Display")); m_pageDisplayItem->setHeader(i18n("Classes Display Options")); @@ -130,7 +118,13 @@ addPage(m_pageDisplayItem); QHBoxLayout * pOptionsLayout = new QHBoxLayout(newPage); - m_pOptionsPage = new ClassOptionsPage(newPage, &m_options); + if (m_pScene->type() != Uml::DiagramType::Class) { + m_pOptionsPage = new ClassOptionsPage(newPage, m_pScene); + } + else { + m_pOptionsPage = new ClassOptionsPage(newPage, &m_options); + } + pOptionsLayout->addWidget(m_pOptionsPage); } @@ -170,21 +164,13 @@ */ void UMLViewDialog::applyPage(KPageWidgetItem *item) { - if (item == m_pageGeneralItem) + if (item == 0) { + // Page not loaded in this dialog + return; + } + else if (item == m_pageDiagramItem) { - checkName(); -//:TODO: m_pScene->setZoom(m_diagramProperties->ui_zoom->value()); - m_pScene->setDocumentation(m_diagramProperties->ui_documentation->toPlainText()); - m_pScene->setSnapSpacing(m_diagramProperties->ui_gridSpaceX->value(), - m_diagramProperties->ui_gridSpaceY->value()); - m_pScene->setLineWidth(m_diagramProperties->ui_lineWidth->value()); - m_pScene->setSnapToGrid(m_diagramProperties->ui_snapToGrid->isChecked()); - m_pScene->setSnapComponentSizeToGrid(m_diagramProperties->ui_snapComponentSizeToGrid->isChecked()); - m_pScene->setSnapGridVisible(m_diagramProperties->ui_checkBoxShowGrid->isChecked()); - m_pScene->setShowOpSig(m_diagramProperties->ui_showOpSigs->isChecked()); - if (m_pScene->type() == Uml::DiagramType::Sequence) { - m_pScene->setAutoIncrementSequence(m_diagramProperties->ui_autoIncrementSequence->isChecked()); - } + m_diagramPropertiesPage->apply(); } else if (item == m_pageStyleItem) { @@ -206,10 +192,10 @@ } else if (item == m_pageDisplayItem) { + m_pOptionsPage->apply(); if (m_pScene->type() != Uml::DiagramType::Class) { return; } - m_pOptionsPage->apply(); m_pScene->setClassWidgetOptions(m_pOptionsPage); // sig = m_pTempWidget->getShowOpSigs(); // showSig = !(sig == Uml::st_NoSig || sig == Uml::st_NoSigNoVis); @@ -221,33 +207,4 @@ } } -/** - * Checks whether the name is unique and sets it if it is. - */ -void UMLViewDialog::checkName() -{ - QString newName = m_diagramProperties->ui_diagramName->text(); - if (newName.length() == 0) { - KMessageBox::sorry(this, i18n("The name you have entered is invalid."), - i18n("Invalid Name"), 0); - m_diagramProperties->ui_diagramName->setText(m_pScene->name()); - return; - } - - if (newName != m_pScene->name()) { - UMLDoc* doc = UMLApp::app()->document(); - UMLView* view = doc->findView(m_pScene->type(), newName); - if (view) { - KMessageBox::sorry(this, i18n("The name you have entered is not unique."), - i18n("Name Not Unique"), 0); - m_diagramProperties->ui_diagramName->setText(m_pScene->name()); - } - else { - // uDebug() << "Cannot find view with name " << newName; - m_pScene->setName(newName); - doc->signalDiagramRenamed(m_pScene->activeView()); - } - } -} - #include "umlviewdialog.moc" diff -Nru umbrello-4.12.3/umbrello/dialogs/umlviewdialog.h umbrello-4.12.90/umbrello/dialogs/umlviewdialog.h --- umbrello-4.12.3/umbrello/dialogs/umlviewdialog.h 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/dialogs/umlviewdialog.h 2014-03-05 15:04:09.000000000 +0000 @@ -17,9 +17,9 @@ // app includes #include "optionstate.h" -#include "ui_diagrampropertiespage.h" class ClassOptionsPage; +class DiagramPropertiesPage; class UMLScene; class UMLView; class UMLWidgetStylePage; @@ -29,13 +29,6 @@ * @author Paul Hensgen * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org */ - -class DiagramPropertiesPage : public QWidget, public Ui::DiagramPropertiesPage -{ -public: - explicit DiagramPropertiesPage(QWidget *parent) : QWidget(parent) { setupUi(this); } -}; - class UMLViewDialog : public KPageDialog { Q_OBJECT @@ -47,7 +40,7 @@ void setupPages(); void setupDiagramPropertiesPage(); - void setupClassPage(); + void setupDisplayPage(); void setupStylePage(); void setupFontPage(); @@ -58,13 +51,13 @@ UMLScene* m_pScene; ///< the scene to represent Settings::OptionState m_options; KFontChooser* m_pChooser; - DiagramPropertiesPage* m_diagramProperties; + DiagramPropertiesPage* m_diagramPropertiesPage; ClassOptionsPage* m_pOptionsPage; UMLWidgetStylePage* m_pStylePage; KPageWidgetItem* m_pageStyleItem; KPageWidgetItem* m_pageFontItem; KPageWidgetItem* m_pageDisplayItem; - KPageWidgetItem* m_pageGeneralItem; + KPageWidgetItem* m_pageDiagramItem; public slots: void slotOk(); diff -Nru umbrello-4.12.3/umbrello/dialogs/umlwidgetstylepage.cpp umbrello-4.12.90/umbrello/dialogs/umlwidgetstylepage.cpp --- umbrello-4.12.3/umbrello/dialogs/umlwidgetstylepage.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/dialogs/umlwidgetstylepage.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -252,7 +252,6 @@ m_options->uiState.backgroundColor = m_BackgroundColorB->color(); m_options->uiState.gridDotColor = m_GridDotColorB->color(); m_options->uiState.lineWidth = m_lineWidthB->value(); - UMLApp::app()->currentView()->umlScene()->setOptionState(*m_options); } if (!m_pUMLWidget) { // when we are on the diagram diff -Nru umbrello-4.12.3/umbrello/docwindow.cpp umbrello-4.12.90/umbrello/docwindow.cpp --- umbrello-4.12.3/umbrello/docwindow.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/docwindow.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -14,6 +14,7 @@ // local includes #include "associationwidget.h" #include "debug_utils.h" +#include "folder.h" #include "icon_utils.h" #include "umldoc.h" #include "umlobject.h" @@ -104,7 +105,12 @@ m_Showing = st_UMLObject; m_pUMLObject = object; m_docTE->setText(m_pUMLObject->doc()); - updateLabel(m_pUMLObject->name()); + if (m_pUMLObject->baseType() == UMLObject::ot_Folder) { + UMLFolder *folder = dynamic_cast(m_pUMLObject); + updateLabel(folder->localName()); + } + else + updateLabel(m_pUMLObject->name()); } /** diff -Nru umbrello-4.12.3/umbrello/dotgenerator.cpp umbrello-4.12.90/umbrello/dotgenerator.cpp --- umbrello-4.12.3/umbrello/dotgenerator.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/dotgenerator.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -336,7 +336,8 @@ else { DotPaintDevice d; QPainter p(&d); - widget->paint(&p, 0); + QStyleOptionGraphicsItem options; + widget->paint(&p, &options); label = d.data().join("\\n"); } @@ -362,7 +363,7 @@ #ifdef DOTGENERATOR_DATA_DEBUG uDebug() << type << params; #endif - QString id = fixID(Uml::ID::toString(widget->id())); + QString id = fixID(Uml::ID::toString(widget->localID())); if (widget->baseType() != WidgetBase::wt_Text) out << "\"" << id << "\"" << " [" << params.join(",") << "];\n"; @@ -425,8 +426,8 @@ #ifdef DOTGENERATOR_DATA_DEBUG uDebug() << type << params; #endif - QString aID = fixID(Uml::ID::toString(assoc->widgetIDForRole(swapId ? Uml::RoleType::A : Uml::RoleType::B))); - QString bID = fixID(Uml::ID::toString(assoc->widgetIDForRole(swapId ? Uml::RoleType::B : Uml::RoleType::A))); + QString aID = fixID(Uml::ID::toString(assoc->widgetLocalIDForRole(swapId ? Uml::RoleType::A : Uml::RoleType::B))); + QString bID = fixID(Uml::ID::toString(assoc->widgetLocalIDForRole(swapId ? Uml::RoleType::B : Uml::RoleType::A))); out << "\"" << aID << "\" -> \"" << bID << "\"" << " [" << params.join(",") << "];\n"; } diff -Nru umbrello-4.12.3/umbrello/entity.cpp umbrello-4.12.90/umbrello/entity.cpp --- umbrello-4.12.3/umbrello/entity.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/entity.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -372,7 +372,7 @@ int UMLEntity::removeEntityAttribute(UMLClassifierListItem* att) { if (!m_List.removeAll((UMLEntityAttribute*)att)) { - uDebug() << "can not find att given in list"; + uDebug() << "cannot find att given in list"; return -1; } emit entityAttributeRemoved(att); diff -Nru umbrello-4.12.3/umbrello/enum.cpp umbrello-4.12.90/umbrello/enum.cpp --- umbrello-4.12.3/umbrello/enum.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/enum.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -75,7 +75,7 @@ void UMLEnum::init() { m_BaseType = UMLObject::ot_Enum; - setStereotype("enum"); + setStereotypeCmd("enum"); } /** @@ -204,7 +204,7 @@ int UMLEnum::removeEnumLiteral(UMLEnumLiteral* literal) { if (!m_List.removeAll(literal)) { - uDebug() << "can not find att given in list"; + uDebug() << "cannot find att given in list"; return -1; } emit enumLiteralRemoved(literal); diff -Nru umbrello-4.12.3/umbrello/folder.cpp umbrello-4.12.90/umbrello/folder.cpp --- umbrello-4.12.3/umbrello/folder.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/folder.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -13,13 +13,13 @@ // app includes #include "debug_utils.h" +#include "model_utils.h" +#include "object_factory.h" +#include "optionstate.h" #include "uml.h" #include "umldoc.h" -#include "umlview.h" -#include "optionstate.h" -#include "object_factory.h" -#include "model_utils.h" #include "umlscene.h" +#include "umlview.h" // kde includes #include @@ -38,7 +38,7 @@ : UMLPackage(name, id) { m_BaseType = UMLObject::ot_Folder; - UMLObject::setStereotype("folder"); + UMLObject::setStereotypeCmd("folder"); } /** @@ -419,7 +419,7 @@ QString error; int line; if (!doc.setContent(data, false, &error, &line)) { - uError() << "Can not set content:" << error << " line:" << line; + uError() << "Cannot set content:" << error << " line:" << line; return false; } QDomNode rootNode = doc.firstChild(); diff -Nru umbrello-4.12.3/umbrello/icon_utils.cpp umbrello-4.12.90/umbrello/icon_utils.cpp --- umbrello-4.12.3/umbrello/icon_utils.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/icon_utils.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -364,6 +364,10 @@ return "draw-brush"; case it_Color_Fill: return "fill-color"; + case it_Import_File: + return "document-import"; + case it_Import_Project: + return "document-import"; case it_Import_Files: return "document-import"; case it_Export_Files: diff -Nru umbrello-4.12.3/umbrello/icon_utils.h umbrello-4.12.90/umbrello/icon_utils.h --- umbrello-4.12.3/umbrello/icon_utils.h 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/icon_utils.h 2014-03-05 15:04:09.000000000 +0000 @@ -150,6 +150,8 @@ it_Parameter_New, it_Color_Line, it_Color_Fill, + it_Import_File, + it_Import_Project, it_Import_Files, it_Export_Files, it_Export_Picture, diff -Nru umbrello-4.12.3/umbrello/import_rose.cpp umbrello-4.12.90/umbrello/import_rose.cpp --- umbrello-4.12.3/umbrello/import_rose.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/import_rose.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -381,8 +381,20 @@ while (!(line = stream.readLine()).isNull()) { linum++; if (line.contains(QRegExp("^\\s*\\(object Petal"))) { - while (!(line = stream.readLine()).isNull() && !line.contains(')')) { + bool finish = false; + while (!(line = stream.readLine()).isNull()) { linum++; // CHECK: do we need petal version info? + if (line.contains(')')) { + finish = true; + line = line.replace(QLatin1String(")"),QLatin1String("")); + } + QStringList a = line.trimmed().split(QRegExp("\\s+")); + if (a.size() == 2) { + if (a[0] == "charSet" && a[1] == "134") + stream.setCodec("GB18030"); + } + if (finish) + break; } if (line.isNull()) break; diff -Nru umbrello-4.12.3/umbrello/layoutgenerator.h umbrello-4.12.90/umbrello/layoutgenerator.h --- umbrello-4.12.3/umbrello/layoutgenerator.h 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/layoutgenerator.h 2014-03-05 15:04:09.000000000 +0000 @@ -235,15 +235,15 @@ QString id; if (m_edgeParameters.contains("id::" + key) && m_edgeParameters["id::" + key] == "swap") - id = fixID(Uml::ID::toString(assoc->widgetIDForRole(Uml::RoleType::A)) + Uml::ID::toString(assoc->widgetIDForRole(Uml::RoleType::B))); + id = fixID(Uml::ID::toString(assoc->widgetLocalIDForRole(Uml::RoleType::A)) + Uml::ID::toString(assoc->widgetLocalIDForRole(Uml::RoleType::B))); else - id = fixID(Uml::ID::toString(assoc->widgetIDForRole(Uml::RoleType::B)) + Uml::ID::toString(assoc->widgetIDForRole(Uml::RoleType::A))); + id = fixID(Uml::ID::toString(assoc->widgetLocalIDForRole(Uml::RoleType::B)) + Uml::ID::toString(assoc->widgetLocalIDForRole(Uml::RoleType::A))); // adjust associations not used in the dot file if (!m_edges.contains(id)) { // shorten line path AssociationLine *path = assoc->associationLine(); - if (path->count() > 2 && assoc->widgetIDForRole(Uml::RoleType::A) != assoc->widgetIDForRole(Uml::RoleType::B)) { + if (path->count() > 2 && assoc->widgetLocalIDForRole(Uml::RoleType::A) != assoc->widgetLocalIDForRole(Uml::RoleType::B)) { while(path->count() > 2) path->removePoint(1); } @@ -276,7 +276,7 @@ } foreach(UMLWidget *widget, scene->widgetList()) { - QString id = Uml::ID::toString(widget->id()); + QString id = Uml::ID::toString(widget->localID()); if (!m_nodes.contains(id)) continue; QPoint p = origin(id); diff -Nru umbrello-4.12.3/umbrello/layouts/activity-export.desktop umbrello-4.12.90/umbrello/layouts/activity-export.desktop --- umbrello-4.12.3/umbrello/layouts/activity-export.desktop 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/layouts/activity-export.desktop 2014-03-05 15:04:09.000000000 +0000 @@ -16,6 +16,7 @@ Name[hu]=Exportálás elrendezés Name[it]=Disposizione di esportazione Name[kk]=ЭкÑпорттың орналаÑуы +Name[ko]=ë ˆì´ì•„웃 내보내기 Name[lt]=Eksportuoti iÅ¡dÄ—stymÄ… Name[mr]=रचना निरà¥à¤¯à¤¾à¤¤ करा Name[nb]=Eksporter utforming @@ -52,6 +53,7 @@ Comment[hu]=Exportálás elrendezés a tevékenység diagramokhoz Comment[it]=Disposizione di esportazione per i diagrammi di attività Comment[kk]=БелÑенділік диаграмма үшін ÑкÑпорттың орналаÑуы +Comment[ko]=í™œë™ ë‹¤ì´ì–´ê·¸ëž¨ì˜ ë ˆì´ì•„웃 내보내기 Comment[lt]=Eksportuoti iÅ¡dÄ—stymÄ… Veiklos diagramoms Comment[nb]=Eksporter utforming for aktivitetsdiagrammer Comment[nl]=Indeling voor activiteitsdiagrammen exporteren diff -Nru umbrello-4.12.3/umbrello/layouts/activity-vertical.desktop umbrello-4.12.90/umbrello/layouts/activity-vertical.desktop --- umbrello-4.12.3/umbrello/layouts/activity-vertical.desktop 1970-01-01 00:00:00.000000000 +0000 +++ umbrello-4.12.90/umbrello/layouts/activity-vertical.desktop 2014-03-05 15:04:09.000000000 +0000 @@ -0,0 +1,118 @@ +[Desktop Entry] +Type=Service +Name=Vertical Layout +Name[bs]=Vertikalni raspored +Name[ca]=Disposició vertical +Name[ca@valencia]=Disposició vertical +Name[cs]=Svislé rozvržení +Name[da]=Lodret layout +Name[de]=Vertikales Layout +Name[el]=ΚατακόÏυφη διάταξη +Name[es]=Disposición vertical +Name[et]=Püstine paigutus +Name[fi]=Pystysuuntainen asettelu +Name[fr]=Disposition verticale +Name[gl]=Disposición vertical +Name[hu]=FüggÅ‘leges elrendezés +Name[it]=Disposizione verticale +Name[kk]=Тік орналаÑуы +Name[ko]=ìˆ˜ì§ ë ˆì´ì•„웃 +Name[lt]=Vertikalus iÅ¡dÄ—stymas +Name[mr]=उभी रचना +Name[nb]=Loddrett utforming +Name[nl]=Verticale indeling +Name[pa]=ਵਰਟੀਕਲ ਲੇਆਉਟ +Name[pl]=UkÅ‚ad pionowy +Name[pt]=Disposição Vertical +Name[pt_BR]=Leiaute vertical +Name[ru]=Вертикальный шаблон +Name[sk]=Zvislé rozloženie +Name[sl]=NavpiÄna postavitev +Name[sr]=УÑправни раÑпоред +Name[sr@ijekavian]=УÑправни раÑпоред +Name[sr@ijekavianlatin]=Uspravni raspored +Name[sr@latin]=Uspravni raspored +Name[sv]=Vertikal layout +Name[tr]=Dikey Düzen +Name[uk]=Вертикальне ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÑƒÐ²Ð°Ð½Ð½Ñ +Name[x-test]=xxVertical Layoutxx +Name[zh_CN]=垂直布局 +Name[zh_TW]=垂直佈局 +Comment=Layout which renders vertical +Comment[bs]=Raspored koji obraÄ‘uej vertikalno +Comment[ca]=DIsposició que renderitza verticalment +Comment[ca@valencia]=DIsposició que renderitza verticalment +Comment[da]=Layout som renderer lodret +Comment[de]=Layout, das vertikal gerendert wird +Comment[el]=Διάταξη που αποτυπώνεται κάθετα +Comment[es]=Diseño que se organiza de forma vertical +Comment[et]=Püstiselt renderdatud paigutus +Comment[fi]=Pystysuuntaan piirtävä asettelu +Comment[fr]=Disposition permettant un rendu vertical +Comment[gl]=Disposición que renderiza de maneira vertical. +Comment[hu]=Elrendezés, amely függÅ‘legesen jelenít meg +Comment[it]=Disposizione che rende in verticale +Comment[kk]=Бір Ò¯Ñтінен бір орналаÑуы +Comment[ko]=수ì§ìœ¼ë¡œ 표시ë˜ëŠ” ë ˆì´ì•„웃 +Comment[nb]=Utforming som tegner opp loddrett +Comment[nl]=Indeling die zich verticaal laat weergeven +Comment[pl]=UkÅ‚ad, który wyÅ›wietla pionowo +Comment[pt]=Uma disposição que representa os itens na vertical +Comment[pt_BR]=Leiaute que representa os itens na vertical +Comment[ru]=Шаблон Ñ Ñ€Ð°Ñположением по вертикали +Comment[sk]=Rozloženie, ktoré renderuje zvislo +Comment[sl]=Postavitev, ki se izriÅ¡e navpiÄno +Comment[sr]=РаÑпоред који иÑцртава уÑправно +Comment[sr@ijekavian]=РаÑпоред који иÑцртава уÑправно +Comment[sr@ijekavianlatin]=Raspored koji iscrtava uspravno +Comment[sr@latin]=Raspored koji iscrtava uspravno +Comment[sv]=Layout som Ã¥terger vertikalt +Comment[tr]=Dikey hazırlanan düzen +Comment[uk]=ÐšÐ¾Ð¼Ð¿Ð¾Ð½ÑƒÐ²Ð°Ð½Ð½Ñ Ð· вертикальним розташуваннÑм елементів +Comment[x-test]=xxLayout which renders verticalxx +Comment[zh_CN]=垂直显示的布局 +Comment[zh_TW]=垂直繪製的佈局 + +[X-UMBRELLO-Dot-Nodes] +# FIXME: graphviz dot not have appropriate node shape yet +type::accept=shape=trapezium +type::branch=shape=diamond +type::end=shape=doublecircle +type::final=shape=circle,label="+" +type::forkjoin=shape=box,style=filled,fillcolor=black,width="0.1",label="" +type::initial=shape=circle +type::invok=shape=box +type::normal=shape=box,style=rounded +# FIXME: add line below the text +type::objectnode=shape=box +type::param=shape=box +type::pin=shape=box,width="0.1",height="0.1" +type::region=shape=box,style="dashed,rounded" +# FIXME: graphviz dot not have appropriate node shape yet +type::send=shape=parallelogram +# FIXME: graphviz dot not have appropriate node shape yet +type::time=shape=box +# all other +type::default=shape=box + +[X-UMBRELLO-Dot-Edges] +# for visual representation +visual::type::anchor=arrowhead=none,style=dashed +visual::type::exception=label="exception" +visual::type::state=arrowhead=normal +ranking::type::default=len=1.5 +# id handling +id::type::default=swap + +[X-UMBRELLO-Dot-Attributes] +graph=splines=polyline,rankdir=TB,outputorder=nodesfirst,ranksep=0.5,nodesep=0.5 +node= +edge= + +[X-UMBRELLO-Dot-Settings] +origin=50,50 +generator=dot + +# see http://www.graphviz.org/pdf/dotguide.pdf +# see http://www.graphviz.org/pdf/neatoguide.pdf +# for dot/neato attribute details diff -Nru umbrello-4.12.3/umbrello/layouts/class-export.desktop umbrello-4.12.90/umbrello/layouts/class-export.desktop --- umbrello-4.12.3/umbrello/layouts/class-export.desktop 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/layouts/class-export.desktop 2014-03-05 15:04:09.000000000 +0000 @@ -16,6 +16,7 @@ Name[hu]=Exportálás elrendezés Name[it]=Disposizione di esportazione Name[kk]=ЭкÑпорттың орналаÑуы +Name[ko]=ë ˆì´ì•„웃 내보내기 Name[lt]=Eksportuoti iÅ¡dÄ—stymÄ… Name[mr]=रचना निरà¥à¤¯à¤¾à¤¤ करा Name[nb]=Eksporter utforming @@ -52,6 +53,7 @@ Comment[hu]=Exportálás elrendezés az osztály diagramokhoz Comment[it]=Disposizione di esportazione per i diagrammi di classe Comment[kk]=ÐšÐ»Ð°Ñ Ð´Ð¸Ð°Ð³Ñ€Ð°Ð¼Ð¼Ð° үшін ÑкÑпорттың орналаÑуы +Comment[ko]=í´ëž˜ìŠ¤ 다ì´ì–´ê·¸ëž¨ì˜ ë ˆì´ì•„웃 내보내기 Comment[lt]=Eksportuoti iÅ¡dÄ—stymÄ… Klasių diagramoms Comment[nb]=Eksporter utforming for klassediagrammer Comment[nl]=Indeling voor klassediagrammen exporteren diff -Nru umbrello-4.12.3/umbrello/layouts/class-horizontal.desktop umbrello-4.12.90/umbrello/layouts/class-horizontal.desktop --- umbrello-4.12.3/umbrello/layouts/class-horizontal.desktop 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/layouts/class-horizontal.desktop 2014-03-05 15:04:09.000000000 +0000 @@ -15,6 +15,7 @@ Name[hu]=Vízszintes elrendezés Name[it]=Disposizione orizzontale Name[kk]=Жатық орналаÑуы +Name[ko]=ìˆ˜í‰ ë ˆì´ì•„웃 Name[lt]=Horizontalus iÅ¡dÄ—stymas Name[mr]=आडवी रचना Name[nb]=Vannrett utforming @@ -51,6 +52,7 @@ Comment[hu]=Elrendezés, amely vízszintesen jelenít meg Comment[it]=Disposizione che rende in orizzontale Comment[kk]=Қатарлап орналаÑуы +Comment[ko]=수í‰ìœ¼ë¡œ 표시ë˜ëŠ” ë ˆì´ì•„웃 Comment[nb]=Utforming som tegner opp vannrett Comment[nl]=Indeling die zich horizontaal laat weergeven Comment[pl]=UkÅ‚ad, który wyÅ›wietla poziomo diff -Nru umbrello-4.12.3/umbrello/layouts/class-vertical.desktop umbrello-4.12.90/umbrello/layouts/class-vertical.desktop --- umbrello-4.12.3/umbrello/layouts/class-vertical.desktop 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/layouts/class-vertical.desktop 2014-03-05 15:04:09.000000000 +0000 @@ -16,6 +16,7 @@ Name[hu]=FüggÅ‘leges elrendezés Name[it]=Disposizione verticale Name[kk]=Тік орналаÑуы +Name[ko]=ìˆ˜ì§ ë ˆì´ì•„웃 Name[lt]=Vertikalus iÅ¡dÄ—stymas Name[mr]=उभी रचना Name[nb]=Loddrett utforming @@ -52,6 +53,7 @@ Comment[hu]=Elrendezés, amely függÅ‘legesen jelenít meg Comment[it]=Disposizione che rende in verticale Comment[kk]=Бір Ò¯Ñтінен бір орналаÑуы +Comment[ko]=수ì§ìœ¼ë¡œ 표시ë˜ëŠ” ë ˆì´ì•„웃 Comment[nb]=Utforming som tegner opp loddrett Comment[nl]=Indeling die zich verticaal laat weergeven Comment[pl]=UkÅ‚ad, który wyÅ›wietla pionowo diff -Nru umbrello-4.12.3/umbrello/layouts/state-export.desktop umbrello-4.12.90/umbrello/layouts/state-export.desktop --- umbrello-4.12.3/umbrello/layouts/state-export.desktop 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/layouts/state-export.desktop 2014-03-05 15:04:09.000000000 +0000 @@ -16,6 +16,7 @@ Name[hu]=Exportálás elrendezés Name[it]=Disposizione di esportazione Name[kk]=ЭкÑпорттың орналаÑуы +Name[ko]=ë ˆì´ì•„웃 내보내기 Name[lt]=Eksportuoti iÅ¡dÄ—stymÄ… Name[mr]=रचना निरà¥à¤¯à¤¾à¤¤ करा Name[nb]=Eksporter utforming @@ -52,6 +53,7 @@ Comment[hu]=Exportálás elrendezés az állapot diagramokhoz Comment[it]=Disposizione di esportazione per i diagrammi di stato Comment[kk]=Күй-жай диаграмма үшін ÑкÑпорттың орналаÑуы +Comment[ko]=ìƒíƒœ 다ì´ì–´ê·¸ëž¨ ë ˆì´ì•„웃 내보내기 Comment[nb]=Eksporter utforming for tilstandsdiagrammer Comment[nl]=Indeling voor statusdiagrammen exporteren Comment[pl]=Eksportuj ukÅ‚ad dla diagramów stanu diff -Nru umbrello-4.12.3/umbrello/layouts/state-vertical.desktop umbrello-4.12.90/umbrello/layouts/state-vertical.desktop --- umbrello-4.12.3/umbrello/layouts/state-vertical.desktop 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/layouts/state-vertical.desktop 2014-03-05 15:04:09.000000000 +0000 @@ -16,6 +16,7 @@ Name[hu]=FüggÅ‘leges elrendezés Name[it]=Disposizione verticale Name[kk]=Тік орналаÑуы +Name[ko]=ìˆ˜ì§ ë ˆì´ì•„웃 Name[lt]=Vertikalus iÅ¡dÄ—stymas Name[mr]=उभी रचना Name[nb]=Loddrett utforming @@ -52,6 +53,7 @@ Comment[hu]=Elrendezés, amely függÅ‘legesen jelenít meg Comment[it]=Disposizione che rende in verticale Comment[kk]=Бір Ò¯Ñтінен бір орналаÑуы +Comment[ko]=수ì§ìœ¼ë¡œ 표시ë˜ëŠ” ë ˆì´ì•„웃 Comment[nb]=Utforming som tegner opp loddrett Comment[nl]=Indeling die zich verticaal laat weergeven Comment[pl]=UkÅ‚ad, który wyÅ›wietla pionowo diff -Nru umbrello-4.12.3/umbrello/layouts/usecase-default.desktop umbrello-4.12.90/umbrello/layouts/usecase-default.desktop --- umbrello-4.12.3/umbrello/layouts/usecase-default.desktop 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/layouts/usecase-default.desktop 2014-03-05 15:04:09.000000000 +0000 @@ -15,6 +15,7 @@ Name[hu]=Használati eset alapértelmezett elrendezés Name[it]=Disposizione predefinita per i casi d'uso Name[kk]=Әдеттті пайдалану ретімен орналаÑуы +Name[ko]=UseCase 기본 ë ˆì´ì•„웃 Name[nb]=Standardutforming for UseCase Name[nl]=Standaard indeling van gebruiksgeval Name[pl]=DomyÅ›lny ukÅ‚ad UseCase @@ -48,6 +49,7 @@ Comment[hu]=Használati eset alapértelmezett elrendezés Comment[it]=Disposizione predefinita per i casi d'uso Comment[kk]=Әдеттті пайдалану ретімен орналаÑуы +Comment[ko]=Usecase 기본 ë ˆì´ì•„웃 Comment[mr]=यà¥à¤œà¤•à¥‡à¤¸ मूलभूत रचना Comment[nb]=Standardutforming for Usecase Comment[nl]=Standaard indeling van gebruiksgeval diff -Nru umbrello-4.12.3/umbrello/listpopupmenu.cpp umbrello-4.12.90/umbrello/listpopupmenu.cpp --- umbrello-4.12.3/umbrello/listpopupmenu.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/listpopupmenu.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -277,55 +277,49 @@ * @param parent The parent to ListPopupMenu. * @param object The WidgetBase to represent a menu for. * @param multi True if multiple items are selected. - * @param unique True if multiple selected items all have - * the same type (e.g. Class, Interface) + * @param uniqueType The type of widget shared by all selected widgets */ -ListPopupMenu::ListPopupMenu(QWidget * parent, WidgetBase * object, - bool multi, bool unique) +ListPopupMenu::ListPopupMenu(QWidget * parent, WidgetBase * object, bool multi, WidgetBase::WidgetType uniqueType) : KMenu(parent) { m_TriggerObject.m_Widget = object; m_TriggerObjectType = tot_Widget; - //make the right menu for the type - //make menu for logical view + if (!object) return; - WidgetBase::WidgetType type = object->baseType(); - // uDebug() << "ListPopupMenu created with multi=" << multi << ", unique=" - // << unique << " for WidgetType=" << WidgetBase::toString(type); if (multi) { - ClassifierWidget *c = NULL; - if (unique && (type == WidgetBase::wt_Class || type == WidgetBase::wt_Interface)) { - c = static_cast(object); - makeMultiClassifierPopup(c); - } - insertSubMenuColor(object->useFillColor()); - addSeparator(); - insert(mt_Cut); - insert(mt_Copy); - insert(mt_Paste); - addSeparator(); - insert(mt_Change_Font_Selection, Icon_Utils::SmallIcon(Icon_Utils::it_Change_Font), i18n("Change Font...")); - insert(mt_Delete_Selection, Icon_Utils::SmallIcon(Icon_Utils::it_Delete), i18n("Delete Selected Items")); + insertMultiSelectionMenu(uniqueType); + } else { + insertSingleSelectionMenu(object); + } - // add this here and not above with the other stuff of the interface - // user might expect it at this position of the context menu - if (unique) { - if (type == WidgetBase::wt_Interface) { - insert(mt_DrawAsCircle_Selection, i18n("Draw as Circle"), CHECKABLE); - setActionChecked(mt_DrawAsCircle_Selection, c->visualProperty(ClassifierWidget::DrawAsCircle)); - insert(mt_ChangeToClass_Selection, i18n("Change into Class")); - } else if (type == WidgetBase::wt_Class) { - UMLClassifier *umlc = c->classifier(); - if (umlc->isAbstract() && umlc->attributes() == 0) - insert(mt_ChangeToInterface_Selection, i18n("Change into Interface")); - } - } + bool bCutState = UMLApp::app()->isCutCopyState(); + setActionEnabled(mt_Cut, bCutState); + setActionEnabled(mt_Copy, bCutState); + setActionEnabled(mt_Paste, false); + setupActionsData(); +} - return; +/** + * Standard destructor. + */ +ListPopupMenu::~ListPopupMenu() +{ + foreach (QAction* action, m_actions) { + delete action; } + m_actions.clear(); +} +/** + * Inserts the menu actions for a widget + * + * @param WidgetBase* object + */ +void ListPopupMenu::insertSingleSelectionMenu(WidgetBase* object) +{ + WidgetBase::WidgetType type = object->baseType(); switch (type) { case WidgetBase::wt_Actor: case WidgetBase::wt_UseCase: @@ -589,25 +583,43 @@ uWarning() << "unhandled WidgetType " << WidgetBase::toString(type); break; }//end switch - - bool bCutState = UMLApp::app()->isCutCopyState(); - setActionEnabled(mt_Cut, bCutState); - setActionEnabled(mt_Copy, bCutState); - setActionEnabled(mt_Paste, false); - setupActionsData(); } /** - * Standard destructor. + * Inserts the menu actions that work on the whole selection of widgets */ -ListPopupMenu::~ListPopupMenu() +void ListPopupMenu::insertMultiSelectionMenu(WidgetBase::WidgetType uniqueType) { - foreach (QAction* action, m_actions) { - delete action; + insertSubMenuAlign(); + + KMenu* color = new KMenu(i18nc("color menu", "Color"), this); + insert(mt_Line_Color_Selection, color, Icon_Utils::SmallIcon(Icon_Utils::it_Color_Line), i18n("Line Color...")); + insert(mt_Fill_Color_Selection, color, Icon_Utils::SmallIcon(Icon_Utils::it_Color_Fill), i18n("Fill Color...")); + insert(mt_Set_Use_Fill_Color_Selection, color, i18n("Use Fill Color")); + insert(mt_Unset_Use_Fill_Color_Selection, color, i18n("No Fill Color")); + + // Add menu actions specific to classifiers + if (uniqueType == WidgetBase::wt_Class || + uniqueType == WidgetBase::wt_Interface) { + makeMultiClassifierShowPopup(uniqueType); } - m_actions.clear(); + + addMenu(color); + + addSeparator(); + insert(mt_Cut); + insert(mt_Copy); + + addSeparator(); + insert(mt_Clone); + insert(mt_Delete); + insert(mt_Resize, i18n("Resize")); + + addSeparator(); + insert(mt_Change_Font_Selection, Icon_Utils::SmallIcon(Icon_Utils::it_Change_Font), i18n("Change Font...")); } + /** * Shortcut for the frequently used addAction() calls. * @@ -655,6 +667,12 @@ case mt_Internalize_Folder: m_actions[m] = addAction(i18n("Internalize Folder")); break; + case mt_Import_Class: + m_actions[m] = addAction(Icon_Utils::BarIcon(Icon_Utils::it_Import_File), i18n("Import File(s)...")); + break; + case mt_Import_Project: + m_actions[m] = addAction(Icon_Utils::BarIcon(Icon_Utils::it_Import_Project), i18n("Import Project...")); + break; case mt_Reset_Label_Positions: m_actions[m] = addAction(i18n("Reset Label Positions")); break; @@ -1040,10 +1058,9 @@ } /** - * Creates a popup menu for a multiple selection of class and - * interface widgets. + * Creates the "Show" submenu in the context menu of one classifier widget */ -void ListPopupMenu::makeMultiClassifierPopup(ClassifierWidget *c) +void ListPopupMenu::makeClassifierShowPopup(ClassifierWidget *c) { WidgetBase::WidgetType type = c->baseType(); ClassifierWidget *cls = NULL; @@ -1052,30 +1069,75 @@ show->setIcon(Icon_Utils::SmallIcon(Icon_Utils::it_Show)); if (type == WidgetBase::wt_Class) { cls = static_cast(c); - insert(mt_Show_Attributes_Selection, show, i18n("Attributes"), CHECKABLE); - setActionChecked(mt_Show_Attributes_Selection, cls->visualProperty(ClassifierWidget::ShowAttributes)); + insert(mt_Show_Attributes, show, i18n("Attributes"), CHECKABLE); + setActionChecked(mt_Show_Attributes, cls->visualProperty(ClassifierWidget::ShowAttributes)); } - insert(mt_Show_Operations_Selection, show, i18n("Operations"), CHECKABLE); - setActionChecked(mt_Show_Operations_Selection, c->visualProperty(ClassifierWidget::ShowOperations)); - insert(mt_Show_Public_Only_Selection, show, i18n("Public Only"), CHECKABLE); - setActionChecked(mt_Show_Public_Only_Selection, c->visualProperty(ClassifierWidget::ShowPublicOnly)); - insert(mt_Visibility_Selection, show, i18n("Visibility"), CHECKABLE); - setActionChecked(mt_Visibility_Selection, c->visualProperty(ClassifierWidget::ShowVisibility)); - insert(mt_Show_Operation_Signature_Selection, show, i18n("Operation Signature"), CHECKABLE); + insert(mt_Show_Operations, show, i18n("Operations"), CHECKABLE); + setActionChecked(mt_Show_Operations, c->visualProperty(ClassifierWidget::ShowOperations)); + insert(mt_Show_Public_Only, show, i18n("Public Only"), CHECKABLE); + setActionChecked(mt_Show_Public_Only, c->visualProperty(ClassifierWidget::ShowPublicOnly)); + insert(mt_Visibility, show, i18n("Visibility"), CHECKABLE); + setActionChecked(mt_Visibility, c->visualProperty(ClassifierWidget::ShowVisibility)); + insert(mt_Show_Operation_Signature, show, i18n("Operation Signature"), CHECKABLE); bool sig = (c->operationSignature() == Uml::SignatureType::SigNoVis || c->operationSignature() == Uml::SignatureType::ShowSig); - setActionChecked(mt_Show_Operation_Signature_Selection, sig); + setActionChecked(mt_Show_Operation_Signature, sig); if (type == WidgetBase::wt_Class) { - insert(mt_Show_Attribute_Signature_Selection, show, i18n("Attribute Signature"), CHECKABLE); + insert(mt_Show_Attribute_Signature, show, i18n("Attribute Signature"), CHECKABLE); sig = (cls->attributeSignature() == Uml::SignatureType::SigNoVis || cls->attributeSignature() == Uml::SignatureType::ShowSig); - setActionChecked(mt_Show_Attribute_Signature_Selection, sig); + setActionChecked(mt_Show_Attribute_Signature, sig); } - insert(mt_Show_Packages_Selection, show, i18n("Package"), CHECKABLE); - setActionChecked(mt_Show_Packages_Selection, c->visualProperty(ClassifierWidget::ShowPackage)); + insert(mt_Show_Packages, show, i18n("Package"), CHECKABLE); + setActionChecked(mt_Show_Packages, c->visualProperty(ClassifierWidget::ShowPackage)); if (type == WidgetBase::wt_Class) { - insert(mt_Show_Stereotypes_Selection, show, i18n("Stereotype"), CHECKABLE); - setActionChecked(mt_Show_Stereotypes_Selection, cls->visualProperty(ClassifierWidget::ShowStereotype)); + insert(mt_Show_Stereotypes, show, i18n("Stereotype"), CHECKABLE); + setActionChecked(mt_Show_Stereotypes, cls->visualProperty(ClassifierWidget::ShowStereotype)); + } + addMenu(show); +} + +/** + * Creates the "Show" submenu the context menu of multiple classifier widgets + */ +void ListPopupMenu::makeMultiClassifierShowPopup(WidgetBase::WidgetType type) +{ + KMenu* show = new KMenu(i18n("Show"), this); + show->setIcon(Icon_Utils::SmallIcon(Icon_Utils::it_Show)); + + KMenu* attributes = new KMenu(i18n("Attributes"), this); + if (type == WidgetBase::wt_Class) { + insert(mt_Show_Attributes_Selection, attributes, i18n("Show")); + insert(mt_Hide_Attributes_Selection, attributes, i18n("Hide")); + insert(mt_Show_Attribute_Signature_Selection, attributes, i18n("Show Signatures")); + insert(mt_Hide_Attribute_Signature_Selection, attributes, i18n("Hide Signatures")); + } + show->addMenu(attributes); + + KMenu* operations = new KMenu(i18n("Operations"), this); + insert(mt_Show_Operations_Selection, operations, i18n("Show")); + insert(mt_Hide_Operations_Selection, operations, i18n("Hide")); + insert(mt_Show_Operation_Signature_Selection, operations, i18n("Show Signatures")); + insert(mt_Hide_Operation_Signature_Selection, operations, i18n("Hide Signatures")); + show->addMenu(operations); + + KMenu* visibility = new KMenu(i18n("Visibility"), this); + insert(mt_Show_Visibility_Selection, visibility, i18n("Show")); + insert(mt_Hide_Visibility_Selection, visibility, i18n("Hide")); + insert(mt_Hide_NonPublic_Selection, visibility, i18n("Hide Non-public members")); + insert(mt_Show_NonPublic_Selection, visibility, i18n("Show Non-public members")); + show->addMenu(visibility); + + KMenu* packages = new KMenu(i18n("Packages"), this); + insert(mt_Show_Packages_Selection, packages, i18n("Show")); + insert(mt_Hide_Packages_Selection, packages, i18n("Hide")); + show->addMenu(packages); + + if (type == WidgetBase::wt_Class) { + KMenu* stereotypes = new KMenu(i18n("Stereotypes"), this); + insert(mt_Show_Stereotypes_Selection, stereotypes, i18n("Show")); + insert(mt_Hide_Stereotypes_Selection, stereotypes, i18n("Hide")); + show->addMenu(stereotypes); } addMenu(show); } @@ -1094,7 +1156,7 @@ insert(mt_Template, menu, Icon_Utils::SmallIcon(Icon_Utils::it_Template_New), i18n("Template...")); addMenu(menu); - makeMultiClassifierPopup(c); + makeClassifierShowPopup(c); insertSubMenuColor(c->useFillColor()); insertStdItems(true, type); @@ -1132,6 +1194,25 @@ } /** + * Add the align actions submenu + */ +void ListPopupMenu::insertSubMenuAlign() +{ + KMenu* alignment = new KMenu(i18nc("align menu", "Align"), this); + insert(mt_Align_Right, alignment, Icon_Utils::SmallIcon(Icon_Utils::it_Align_Right), i18n("Align Right")); + insert(mt_Align_Left, alignment, Icon_Utils::SmallIcon(Icon_Utils::it_Align_Left), i18n("Align Left")); + insert(mt_Align_Top, alignment, Icon_Utils::SmallIcon(Icon_Utils::it_Align_Top), i18n("Align Top")); + insert(mt_Align_Bottom, alignment, Icon_Utils::SmallIcon(Icon_Utils::it_Align_Bottom), i18n("Align Bottom")); + + insert(mt_Align_VerticalMiddle, alignment, Icon_Utils::SmallIcon(Icon_Utils::it_Align_VerticalMiddle), i18n("Align Vertical Middle")); + insert(mt_Align_HorizontalMiddle, alignment, Icon_Utils::SmallIcon(Icon_Utils::it_Align_HorizontalMiddle), i18n("Align Horizontal Middle")); + insert(mt_Align_VerticalDistribute, alignment, Icon_Utils::SmallIcon(Icon_Utils::it_Align_VerticalDistribute), i18n("Align Vertical Distribute")); + insert(mt_Align_HorizontalDistribute, alignment, Icon_Utils::SmallIcon(Icon_Utils::it_Align_HorizontalDistribute), i18n("Align Horizontal Distribute")); + + addMenu(alignment); +} + +/** * Shortcut for commonly used sub menu initializations. * * @param fc The "Use Fill Color" is checked. @@ -1147,47 +1228,6 @@ } /** - * Utility: Convert a MenuType value to a Diagram_Type value. - */ -Uml::DiagramType::Enum ListPopupMenu::convert_MT_DT(MenuType mt) -{ - Uml::DiagramType::Enum type = Uml::DiagramType::Undefined; - - switch (mt) { - case mt_UseCase_Diagram: - type = Uml::DiagramType::UseCase; - break; - case mt_Class_Diagram: - type = Uml::DiagramType::Class; - break; - case mt_Sequence_Diagram: - type = Uml::DiagramType::Sequence; - break; - case mt_Collaboration_Diagram: - type = Uml::DiagramType::Collaboration; - break; - case mt_State_Diagram: - type = Uml::DiagramType::State; - break; - case mt_Activity_Diagram: - type = Uml::DiagramType::Activity; - break; - case mt_Component_Diagram: - type = Uml::DiagramType::Component; - break; - case mt_Deployment_Diagram: - type = Uml::DiagramType::Deployment; - break; - case mt_EntityRelationship_Diagram: - type = Uml::DiagramType::EntityRelationship; - break; - default: - break; - } - return type; -} - -/** * Utility: Convert a MenuType value to an ObjectType value. */ UMLObject::ObjectType ListPopupMenu::convert_MT_OT(MenuType mt) @@ -1406,6 +1446,9 @@ addSeparator(); insert(mt_Paste); addSeparator(); + insert(mt_Import_Project); + insert(mt_Import_Class); + addSeparator(); insert(mt_Expand_All); insert(mt_Collapse_All); break; @@ -1451,6 +1494,7 @@ case mt_Logical_Folder: insertContainerItems(true); insertStdItems(); + insert(mt_Import_Project); insertSubmodelAction(); addSeparator(); insert(mt_Expand_All); @@ -1502,11 +1546,8 @@ case mt_Component_Diagram: case mt_Deployment_Diagram: case mt_EntityRelationship_Diagram: - //don't insert standard items because cut/copy are not currently - // possible with tabbed diagrams (it didn't work anyway) - //insertStdItems(false); - insert(mt_Rename); - insert(mt_Delete); + insertStdItems(false); + insert(mt_Clone); insert(mt_Export_Image); insert(mt_Properties); break; @@ -1595,6 +1636,9 @@ case mt_Class: insertSubMenuNew(type); insertStdItems(); + addSeparator(); + insert(mt_Import_Class); + addSeparator(); insert(mt_Properties); break; diff -Nru umbrello-4.12.3/umbrello/listpopupmenu.h umbrello-4.12.90/umbrello/listpopupmenu.h --- umbrello-4.12.3/umbrello/listpopupmenu.h 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/listpopupmenu.h 2014-03-05 15:04:09.000000000 +0000 @@ -12,9 +12,9 @@ #define LISTPOPUPMENU_H #include "basictypes.h" -#include "widgetbase.h" #include "umllistviewitem.h" #include "umlobject.h" +#include "widgetbase.h" #include @@ -134,22 +134,34 @@ mt_ForeignKeyConstraint_Selected, mt_CheckConstraint_Selected, mt_Association_Selected, // Association without role names - mt_Show_Attributes, - mt_Show_Attributes_Selection, // SHOWATTS, multiple items - mt_Show_Operations, - mt_Show_Operations_Selection, // SHOWOPS, multiple items - mt_Show_Packages, - mt_Show_Packages_Selection, // SHOWPACKAGE, multiple items + mt_Show_Attributes, // Toggle visual property on a widget + mt_Show_Attributes_Selection, // Set visual property on multiple widgets + mt_Hide_Attributes_Selection, // Unset visual property on multiple widgets + mt_Show_Operations, // Toggle 'show operations' + mt_Show_Operations_Selection, // Show operations + mt_Hide_Operations_Selection, // Hide operations + mt_Show_Packages, // etc... + mt_Show_Packages_Selection, + mt_Hide_Packages_Selection, + mt_Show_Public_Only, + mt_Hide_NonPublic_Selection, // Could be named "show public only" + mt_Show_NonPublic_Selection, // Could be named "hide public only" (crazy!) mt_Show_Stereotypes, - mt_Show_Stereotypes_Selection, // SHOWSTEREOTYPE, multiple items + mt_Show_Stereotypes_Selection, + mt_Hide_Stereotypes_Selection, mt_Visibility, - mt_Visibility_Selection, // SCOPE, multiple items + mt_Show_Visibility_Selection, + mt_Hide_Visibility_Selection, + mt_Show_Operation_Signature, + mt_Show_Operation_Signature_Selection, + mt_Hide_Operation_Signature_Selection, + mt_Show_Attribute_Signature, + mt_Show_Attribute_Signature_Selection, + mt_Hide_Attribute_Signature_Selection, + mt_DrawAsCircle, - mt_DrawAsCircle_Selection, // DRAWASCIRCLE, multiple items mt_ChangeToClass, - mt_ChangeToClass_Selection, mt_ChangeToInterface, - mt_ChangeToInterface_Selection, mt_Rename_Object, mt_Select_Operation, mt_Anchor, @@ -157,6 +169,8 @@ mt_Rename, mt_Delete, mt_Export_Image, + mt_Import_Class, + mt_Import_Project, mt_Sequence_Number, mt_Cut, mt_Copy, @@ -165,10 +179,6 @@ mt_Redo, mt_Undo, mt_Link_Docs, - mt_Show_Operation_Signature, - mt_Show_Operation_Signature_Selection, //SHOWOPSIG, multiple items - mt_Show_Attribute_Signature, - mt_Show_Attribute_Signature_Selection, //SHOWATTSIG, multiple items mt_Message_Text, mt_Collaboration_Message, mt_FloatText, @@ -179,11 +189,14 @@ mt_AttributeAssociation, // Rendering of an attribute as an association mt_RoleNameA, mt_RoleNameB, - mt_Delete_Selection, mt_Reset_Label_Positions, mt_Line_Color, + mt_Line_Color_Selection, mt_Fill_Color, + mt_Fill_Color_Selection, mt_Use_Fill_Color, + mt_Set_Use_Fill_Color_Selection, + mt_Unset_Use_Fill_Color_Selection, mt_Default_Properties, mt_Rename_MultiA, mt_Rename_MultiB, @@ -211,8 +224,6 @@ mt_Refactoring, mt_ViewCode, // view code document contents mt_Clone, // Create a deep copy of the object. - mt_Show_Public_Only, // (not currently used) - mt_Show_Public_Only_Selection, // Show public operations/attributes only. mt_Externalize_Folder, // Mark folder for saving as separate submodel mt_Internalize_Folder, // Reintegrate separate submodel into main model @@ -233,6 +244,15 @@ mt_LayoutOrthogonal, // associations with orthogonal lines mt_LayoutPolyline, // associations with polylines + mt_Align_Right, + mt_Align_Left, + mt_Align_Top, + mt_Align_Bottom, + mt_Align_VerticalMiddle, + mt_Align_HorizontalMiddle, + mt_Align_VerticalDistribute, + mt_Align_HorizontalDistribute, + mt_Undefined = - 1 }; @@ -250,12 +270,12 @@ explicit ListPopupMenu(QWidget* parent, MenuType type = mt_Undefined, UMLView* view = 0); ListPopupMenu(QWidget* parent, MenuType type, WidgetBase *widget); ListPopupMenu(QWidget* parent, UMLListViewItem::ListViewType type, UMLObject* object); - ListPopupMenu(QWidget* parent, WidgetBase* object, bool multi = false, bool unique = false); + ListPopupMenu(QWidget* parent, WidgetBase* object, bool multi = false, + WidgetBase::WidgetType uniqueType = WidgetBase::wt_UMLWidget); virtual ~ListPopupMenu(); static UMLObject::ObjectType convert_MT_OT(MenuType mt); - static Uml::DiagramType::Enum convert_MT_DT(MenuType mt); static ListPopupMenu* menuFromAction(QAction *action); static MenuType typeFromAction(QAction *action); @@ -270,6 +290,9 @@ private: + void insertSingleSelectionMenu(WidgetBase* object); + void insertMultiSelectionMenu(WidgetBase::WidgetType uniqueType); + void insert(MenuType m); void insert(const MenuType m, KMenu* menu); void insert(const MenuType m, const QIcon & icon, const QString & text); @@ -286,11 +309,13 @@ void insertSubmodelAction(); void insertLayoutItems(UMLView *view); - void makeMultiClassifierPopup(ClassifierWidget *c); void makeClassifierPopup(ClassifierWidget *c); + void makeMultiClassifierShowPopup(WidgetBase::WidgetType type); + void makeClassifierShowPopup(ClassifierWidget *c); KMenu* makeCategoryTypeMenu(UMLCategory* category); void insertSubMenuNew(MenuType type); + void insertSubMenuAlign(); void insertSubMenuColor(bool fc); void setupDiagramMenu(UMLView* view); diff -Nru umbrello-4.12.3/umbrello/main.cpp umbrello-4.12.90/umbrello/main.cpp --- umbrello-4.12.3/umbrello/main.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/main.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -78,6 +78,7 @@ options.add("export ", ki18n("export diagrams to extension and exit")); options.add("export-formats", ki18n("list available export extensions")); options.add("directory ", ki18n("the local directory to save the exported diagrams in"), I18N_NOOP("the directory of the file")); + options.add("import-files", ki18n("import files")); options.add("use-folders", ki18n("keep the tree structure used to store the views in the document in the target directory")); KCmdLineArgs::addCmdLineOptions(options); // Add our own options. @@ -88,8 +89,14 @@ kRestoreMainWindows< UMLApp >(); } else { KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); - bool showGUI = getShowGUI(args); + if (args->isSet("export-formats")) { + foreach(const QString& type, UMLViewImageExporterModel::supportedImageTypes()) + fprintf(stdout, "%s\n", qPrintable(type)); + return 0; + } + + bool showGUI = getShowGUI(args); UMLApp* uml = new UMLApp(); app.processEvents(); @@ -97,13 +104,16 @@ uml->show(); } - initDocument(args); + if (args->isSet("import-files") && args->count() > 0) { + QStringList importList; + for (int i = 0; i < args->count(); i++) + importList.append(args->url(i).toLocalFile()); + uml->newDocument(); + uml->importFiles(&importList); + } else + initDocument(args); + - if (args->isSet("export-formats")) { - foreach(const QString& type, UMLViewImageExporterModel::supportedImageTypes()) - fprintf(stdout, "%s\n", qPrintable(type)); - return 0; - } // export option QStringList exportOpt = args->getOptionList("export"); if (exportOpt.size() > 0) { diff -Nru umbrello-4.12.3/umbrello/model_utils.cpp umbrello-4.12.90/umbrello/model_utils.cpp --- umbrello-4.12.3/umbrello/model_utils.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/model_utils.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -1012,6 +1012,85 @@ } /** + * Check if a listviewitem of type childType is allowed + * as child of type parentType + */ +bool typeIsAllowedInType(UMLListViewItem::ListViewType childType, + UMLListViewItem::ListViewType parentType) +{ + switch (childType) { + case UMLListViewItem::lvt_Class: + case UMLListViewItem::lvt_Package: + case UMLListViewItem::lvt_Interface: + case UMLListViewItem::lvt_Enum: + return parentType == UMLListViewItem::lvt_Logical_View || + parentType == UMLListViewItem::lvt_Class || + parentType == UMLListViewItem::lvt_Package || + parentType == UMLListViewItem::lvt_Logical_Folder; + case UMLListViewItem::lvt_Attribute: + case UMLListViewItem::lvt_EntityAttribute: + return parentType == UMLListViewItem::lvt_Entity; + case UMLListViewItem::lvt_Operation: + return parentType == UMLListViewItem::lvt_Class || + parentType == UMLListViewItem::lvt_Interface; + case UMLListViewItem::lvt_Datatype: + return parentType == UMLListViewItem::lvt_Logical_Folder || + parentType == UMLListViewItem::lvt_Datatype_Folder || + parentType == UMLListViewItem::lvt_Class || + parentType == UMLListViewItem::lvt_Interface || + parentType == UMLListViewItem::lvt_Package; + case UMLListViewItem::lvt_Class_Diagram: + case UMLListViewItem::lvt_Collaboration_Diagram: + case UMLListViewItem::lvt_State_Diagram: + case UMLListViewItem::lvt_Activity_Diagram: + case UMLListViewItem::lvt_Sequence_Diagram: + return parentType == UMLListViewItem::lvt_Logical_Folder || + parentType == UMLListViewItem::lvt_Logical_View; + case UMLListViewItem::lvt_Logical_Folder: + return parentType == UMLListViewItem::lvt_Logical_Folder || + parentType == UMLListViewItem::lvt_Logical_View; + case UMLListViewItem::lvt_UseCase_Folder: + return parentType == UMLListViewItem::lvt_UseCase_Folder || + parentType == UMLListViewItem::lvt_UseCase_View; + case UMLListViewItem::lvt_Component_Folder: + return parentType == UMLListViewItem::lvt_Component_Folder || + parentType == UMLListViewItem::lvt_Component_View; + case UMLListViewItem::lvt_Deployment_Folder: + return parentType == UMLListViewItem::lvt_Deployment_Folder || + parentType == UMLListViewItem::lvt_Deployment_View; + case UMLListViewItem::lvt_EntityRelationship_Folder: + return parentType == UMLListViewItem::lvt_EntityRelationship_Folder || + parentType == UMLListViewItem::lvt_EntityRelationship_Model; + case UMLListViewItem::lvt_Actor: + case UMLListViewItem::lvt_UseCase: + case UMLListViewItem::lvt_UseCase_Diagram: + return parentType == UMLListViewItem::lvt_UseCase_Folder || + parentType == UMLListViewItem::lvt_UseCase_View; + case UMLListViewItem::lvt_Subsystem: + return parentType == UMLListViewItem::lvt_Component_Folder || + parentType == UMLListViewItem::lvt_Subsystem; + case UMLListViewItem::lvt_Component: + return parentType == UMLListViewItem::lvt_Component_Folder || + parentType == UMLListViewItem::lvt_Component || + parentType == UMLListViewItem::lvt_Subsystem; + case UMLListViewItem::lvt_Artifact: + case UMLListViewItem::lvt_Component_Diagram: + return parentType == UMLListViewItem::lvt_Component_Folder || + parentType == UMLListViewItem::lvt_Component_View; + break; + case UMLListViewItem::lvt_Node: + case UMLListViewItem::lvt_Deployment_Diagram: + return parentType == UMLListViewItem::lvt_Deployment_Folder; + case UMLListViewItem::lvt_Entity: + case UMLListViewItem::lvt_EntityRelationship_Diagram: + case UMLListViewItem::lvt_Category: + return parentType == UMLListViewItem::lvt_EntityRelationship_Folder; + default: + return false; + } +} + +/** * Return true if the listview type is a diagram. */ bool typeIsDiagram(UMLListViewItem::ListViewType type) diff -Nru umbrello-4.12.3/umbrello/model_utils.h umbrello-4.12.90/umbrello/model_utils.h --- umbrello-4.12.3/umbrello/model_utils.h 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/model_utils.h 2014-03-05 15:04:09.000000000 +0000 @@ -73,6 +73,8 @@ bool typeIsDiagram(UMLListViewItem::ListViewType type); bool typeIsClassifierList(UMLListViewItem::ListViewType type); bool typeIsClassifier(UMLListViewItem::ListViewType type); +bool typeIsAllowedInType(UMLListViewItem::ListViewType childType, + UMLListViewItem::ListViewType parentType); Uml::ModelType::Enum convert_DT_MT(Uml::DiagramType::Enum dt); UMLListViewItem::ListViewType convert_MT_LVT(Uml::ModelType::Enum mt); diff -Nru umbrello-4.12.3/umbrello/object_factory.cpp umbrello-4.12.90/umbrello/object_factory.cpp --- umbrello-4.12.3/umbrello/object_factory.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/object_factory.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -135,13 +135,22 @@ uWarning() << "error unknown type: " << UMLObject::toString(type); return NULL; } - o->setUMLPackage(parentPkg); - // will be called in cmdCreateUMLObject - //parentPkg->addObject(o); + // One user action can result in multiple commands when adding objects via + // the toolbar. E.g. "create uml object" and "create widget". Wrap all + // commands in one macro. When adding items via list view, this macro will + // contain only the "create uml object" command. + UMLApp::app()->beginMacro(i18n("Create UML object : %1", name)); + + o->setUMLPackage(parentPkg); UMLApp::app()->executeCommand(new Uml::CmdCreateUMLObject(o)); + + UMLApp::app()->document()->signalUMLObjectCreated(o); + qApp->processEvents(); + + UMLApp::app()->endMacro(); return o; } @@ -185,10 +194,15 @@ return o; } } - bool ok = false; - QString name = Model_Utils::uniqObjectName(type, parentPkg, n); + bool bValidNameEntered = false; - do { + QString name = Model_Utils::uniqObjectName(type, parentPkg, n); + if (name == n) { + bValidNameEntered = true; + } + + bool ok = false; + while (bValidNameEntered == false) { name = KInputDialog::getText(i18nc("UMLObject name", "Name"), i18n("Enter name:"), name, &ok, (QWidget*)UMLApp::app()); if (!ok) { return 0; @@ -210,7 +224,8 @@ continue; } bValidNameEntered = true; - } while (bValidNameEntered == false); + } + UMLObject *o = createNewUMLObject(type, name, parentPkg); return o; } @@ -237,62 +252,63 @@ * * @param parent The parent concept * @param type The type to create + * @param name Optional name of object (skips creation dialog) * @return Pointer to the UMLClassifierListItem created */ -UMLClassifierListItem* createChildObject(UMLClassifier* parent, UMLObject::ObjectType type) +UMLClassifierListItem* createChildObject(UMLClassifier* parent, UMLObject::ObjectType type, const QString& name) { UMLObject* returnObject = NULL; switch (type) { case UMLObject::ot_Attribute: { UMLClassifier *c = dynamic_cast(parent); if (c && !c->isInterface()) - returnObject = c->createAttribute(); + returnObject = c->createAttribute(name); break; } case UMLObject::ot_EntityAttribute: { UMLEntity *e = dynamic_cast(parent); if (e) { - returnObject = e->createAttribute(); + returnObject = e->createAttribute(name); } break; } case UMLObject::ot_Operation: { UMLClassifier *c = dynamic_cast(parent); if (c) - returnObject = c->createOperation(); + returnObject = c->createOperation(name); break; } case UMLObject::ot_Template: { UMLClassifier *c = dynamic_cast(parent); if (c) - returnObject = c->createTemplate(); + returnObject = c->createTemplate(name); break; } case UMLObject::ot_EnumLiteral: { UMLEnum* umlenum = dynamic_cast(parent); if (umlenum) { - returnObject = umlenum->createEnumLiteral(); + returnObject = umlenum->createEnumLiteral(name); } break; } case UMLObject::ot_UniqueConstraint: { UMLEntity* umlentity = dynamic_cast(parent); if (umlentity) { - returnObject = umlentity->createUniqueConstraint(); + returnObject = umlentity->createUniqueConstraint(name); } break; } case UMLObject::ot_ForeignKeyConstraint: { UMLEntity* umlentity = dynamic_cast(parent); if (umlentity) { - returnObject = umlentity->createForeignKeyConstraint(); + returnObject = umlentity->createForeignKeyConstraint(name); } break; } case UMLObject::ot_CheckConstraint: { UMLEntity* umlentity = dynamic_cast(parent); if (umlentity) { - returnObject = umlentity->createCheckConstraint(); + returnObject = umlentity->createCheckConstraint(name); } break; } diff -Nru umbrello-4.12.3/umbrello/object_factory.h umbrello-4.12.90/umbrello/object_factory.h --- umbrello-4.12.3/umbrello/object_factory.h 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/object_factory.h 2014-03-05 15:04:09.000000000 +0000 @@ -28,7 +28,9 @@ UMLPackage *parentPkg = 0, bool solicitNewName = true); -UMLClassifierListItem* createChildObject(UMLClassifier *parent, UMLObject::ObjectType type); +UMLClassifierListItem* createChildObject(UMLClassifier *parent, + UMLObject::ObjectType type, + const QString& name = QString()); UMLAttribute *createAttribute(UMLObject *parent, const QString& name, UMLObject *type = 0); diff -Nru umbrello-4.12.3/umbrello/refactoring/refactoringassistant.cpp umbrello-4.12.90/umbrello/refactoring/refactoringassistant.cpp --- umbrello-4.12.3/umbrello/refactoring/refactoringassistant.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/refactoring/refactoringassistant.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -617,7 +617,7 @@ QTreeWidgetItem *parent = item->parent(); c = dynamic_cast(findUMLObject(parent)); if (!c) { - uWarning() << "No classifier - can not create!"; + uWarning() << "No classifier - cannot create!"; return; } } diff -Nru umbrello-4.12.3/umbrello/toolbarstate.cpp umbrello-4.12.90/umbrello/toolbarstate.cpp --- umbrello-4.12.3/umbrello/toolbarstate.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/toolbarstate.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -146,6 +146,11 @@ UMLWidget* currentWidget = m_pUMLScene->widgetAt(m_pMouseEvent->scenePos()); AssociationWidget* currentAssociation = associationAt(m_pMouseEvent->scenePos()); + + if (currentWidget || currentAssociation) { + ome->accept(); + } + if (currentWidget) { setCurrentWidget(currentWidget); mouseDoubleClickWidget(); diff -Nru umbrello-4.12.3/umbrello/umbrello.kcfg umbrello-4.12.90/umbrello/umbrello.kcfg --- umbrello-4.12.3/umbrello/umbrello.kcfg 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/umbrello.kcfg 2014-03-05 15:04:09.000000000 +0000 @@ -22,7 +22,7 @@ Undo Support is enabled when this is true - false + true diff -Nru umbrello-4.12.3/umbrello/umlcanvasobject.cpp umbrello-4.12.90/umbrello/umlcanvasobject.cpp --- umbrello-4.12.3/umbrello/umlcanvasobject.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/umlcanvasobject.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -117,7 +117,7 @@ int UMLCanvasObject::removeAssociationEnd(UMLAssociation * assoc) { if (!hasAssociation(assoc) || !m_List.removeAll(assoc)) { - DEBUG(DBG_SRC) << "can not find given assoc " << assoc << " in list"; + DEBUG(DBG_SRC) << "cannot find given assoc " << assoc << " in list"; return -1; } UMLApp::app()->document()->removeAssociation(assoc, false); diff -Nru umbrello-4.12.3/umbrello/uml.cpp umbrello-4.12.90/umbrello/uml.cpp --- umbrello-4.12.3/umbrello/uml.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/uml.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -24,6 +24,7 @@ #include "cmds.h" #include "umbrellosettings.h" #include "statusbartoolbutton.h" + // code generation #include "codegenerator.h" #include "codegenerationpolicy.h" @@ -93,6 +94,7 @@ #include #include #include +#include #include @@ -281,6 +283,11 @@ impWizard->setText(i18n("Code &Importing Wizard...")); connect(impWizard, SIGNAL(triggered(bool)), this, SLOT(slotImportingWizard())); + QAction* importProject = actionCollection()->addAction("import_project"); + importProject->setIcon(Icon_Utils::SmallIcon(Icon_Utils::it_Import_Project)); + importProject->setText(i18n("Import &Project...")); + connect(importProject, SIGNAL(triggered(bool)), this, SLOT(slotImportProject())); + QAction* genWizard = actionCollection()->addAction("generation_wizard"); genWizard->setIcon(Icon_Utils::SmallIcon(Icon_Utils::it_Export_Files)); genWizard->setText(i18n("&Code Generation Wizard...")); @@ -418,10 +425,18 @@ viewShowTree->setText(i18n("&Tree View")); connect(viewShowTree, SIGNAL(triggered(bool)), this, SLOT(slotShowTreeView(bool))); + viewShowDebug = actionCollection()->add("view_show_debug"); + viewShowDebug->setText(i18n("&Debugging")); + connect(viewShowDebug, SIGNAL(triggered(bool)), this, SLOT(slotShowDebugView(bool))); + viewShowDoc = actionCollection()->add("view_show_doc"); viewShowDoc->setText(i18n("&Documentation")); connect(viewShowDoc, SIGNAL(triggered(bool)), this, SLOT(slotShowDocumentationView(bool))); + viewShowLog = actionCollection()->add("view_show_log"); + viewShowLog->setText(i18n("&Logging")); + connect(viewShowLog, SIGNAL(triggered(bool)), this, SLOT(slotShowLogView(bool))); + viewShowCmdHistory = actionCollection()->add("view_show_undo"); viewShowCmdHistory->setText(i18n("&Command history")); connect(viewShowCmdHistory, SIGNAL(triggered(bool)), this, SLOT(slotShowCmdHistoryView(bool))); @@ -441,7 +456,7 @@ deleteDiagram = actionCollection()->addAction("view_delete"); deleteDiagram->setIcon(Icon_Utils::SmallIcon(Icon_Utils::it_Delete)); - deleteDiagram->setText(i18n("&Delete")); + deleteDiagram->setText(i18n("&Delete Diagram")); connect(deleteDiagram, SIGNAL(triggered(bool)), this, SLOT(slotDeleteDiagram())); viewExportImage = actionCollection()->addAction("view_export_image"); @@ -820,6 +835,12 @@ m_listDock->setWidget(m_listView); connect(m_listDock, SIGNAL(visibilityChanged(bool)), viewShowTree, SLOT(setChecked(bool))); + m_debugDock = new QDockWidget(i18n("&Debug"), this); + m_debugDock->setObjectName("DebugDock"); + addDockWidget(Qt::LeftDockWidgetArea, m_debugDock); + m_debugDock->setWidget(Tracer::instance()); + connect(m_debugDock, SIGNAL(visibilityChanged(bool)), viewShowLog, SLOT(setChecked(bool))); + // create the documentation viewer m_documentationDock = new QDockWidget(i18n("Doc&umentation"), this); m_documentationDock->setObjectName("DocumentationDock"); @@ -841,12 +862,22 @@ m_cmdHistoryDock->setWidget(m_pQUndoView); connect(m_cmdHistoryDock, SIGNAL(visibilityChanged(bool)), viewShowCmdHistory, SLOT(setChecked(bool))); + // create the log viewer + m_logDock = new QDockWidget(i18n("&Log"), this); + m_logDock->setObjectName("LogDock"); + addDockWidget(Qt::LeftDockWidgetArea, m_logDock); + m_logWindow = new QListWidget(m_logDock); + m_logWindow->setObjectName("LOGWINDOW"); + m_logDock->setWidget(m_logWindow); + connect(m_logDock, SIGNAL(visibilityChanged(bool)), viewShowLog, SLOT(setChecked(bool))); + // create the property viewer //m_propertyDock = new QDockWidget(i18n("&Properties"), this); //m_propertyDock->setObjectName("PropertyDock"); //addDockWidget(Qt::LeftDockWidgetArea, m_propertyDock); //:TODO: tabifyDockWidget(m_documentationDock, m_cmdHistoryDock); + tabifyDockWidget(m_cmdHistoryDock, m_logDock); //tabifyDockWidget(m_cmdHistoryDock, m_propertyDock); //:TODO: } @@ -1516,7 +1547,8 @@ void UMLApp::createDiagram(Uml::DiagramType::Enum type) { QString diagramName = m_doc->createDiagramName(type); - executeCommand(new Uml::CmdCreateDiagram(m_doc, type, diagramName)); + if (!diagramName.isEmpty()) + executeCommand(new Uml::CmdCreateDiagram(m_doc, type, diagramName)); } /** @@ -1676,6 +1708,16 @@ } /** + * Returns the log window used. + * + * @return the log window being used + */ +QListWidget* UMLApp::logWindow() const +{ + return m_logWindow; +} + +/** * Sets whether the program has been modified. * This will change how the program saves/exits. * @@ -1694,7 +1736,7 @@ if (m_loading == false) { if (m_doc) { - DEBUG(DBG_SRC) << m_doc->url().fileName(); + DEBUG(DBG_SRC) << "Modified file=" << m_doc->url().fileName(); setCaption(m_doc->url().fileName(), modified); //add disk icon to taskbar if modified } else { @@ -2390,6 +2432,12 @@ viewShowTree->setChecked(state); } +void UMLApp::slotShowDebugView(bool state) +{ + m_debugDock->setVisible(state); + viewShowDebug->setChecked(state); +} + void UMLApp::slotShowDocumentationView(bool state) { m_documentationDock->setVisible(state); @@ -2402,6 +2450,12 @@ viewShowCmdHistory->setChecked(state); } +void UMLApp::slotShowLogView(bool state) +{ + m_logDock->setVisible(state); + viewShowLog->setChecked(state); +} + /** * Menu selection for clear current view. */ @@ -2504,7 +2558,12 @@ */ void UMLApp::importFiles(QStringList* fileList) { - if (! fileList->isEmpty()) { + if (!fileList->isEmpty()) { + bool saveState = listView()->parentWidget()->isVisible(); + listView()->parentWidget()->setVisible(false); + logWindow()->parentWidget()->setVisible(true); + logWindow()->clear(); + const QString& firstFile = fileList->first(); ClassImport *classImporter = ClassImport::createImporterByFileExt(firstFile); classImporter->importFiles(*fileList); @@ -2514,6 +2573,52 @@ // Allowing undo of the whole class importing. I think it eats a lot of memory. // Setting the modification, but without allowing undo. m_doc->setModified(true); + listView()->parentWidget()->setVisible(saveState); + } +} + +/** + * Import class menu selection. + */ +void UMLApp::slotImportClass() +{ + QStringList filters = Uml::ProgrammingLanguage::toExtensions(UMLApp::app()->activeLanguage()); + QString f = filters.join(" ") + QLatin1String("|") + Uml::ProgrammingLanguage::toExtensionsDescription(UMLApp::app()->activeLanguage()); + + QStringList files = KFileDialog::getOpenFileNames(KUrl(), f, this, i18n("Select file(s) to import:")); + if (!files.isEmpty()) { + importFiles(&files); + } +} + +/** + * @brief getFiles + * @param files + * @param path + * @param filters + */ +void getFiles(QStringList& files, const QString& path, QStringList& filters) +{ + QDir searchDir(path); + if (searchDir.exists()) { + foreach (const QFileInfo &file, searchDir.entryList(filters, QDir::Files)) + files.append(searchDir.absoluteFilePath(file.fileName())); + foreach (const QFileInfo &subDir, searchDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::NoSymLinks)) + getFiles(files, searchDir.absoluteFilePath(subDir.fileName()), filters); + } +} + +/** + * Import project menu selection. + */ +void UMLApp::slotImportProject() +{ + QStringList listFile; + QString dir = KFileDialog::getExistingDirectory(KUrl(),this, i18n("Select directory to import:")); + if (!dir.isEmpty()) { + QStringList filter = Uml::ProgrammingLanguage::toExtensions(UMLApp::app()->activeLanguage()); + getFiles(listFile, dir, filter); + importFiles(&listFile); } } @@ -2594,7 +2699,7 @@ QWidget *f = focusWidget(); if (f == m_listView) { QWidgetAction *o = static_cast(sender()); - if (o->objectName() == "delete_selected") { + if (o && o->objectName() == "delete_selected") { m_listView->slotDeleteSelectedItems(); } return; @@ -2836,7 +2941,7 @@ if (lvitem) { m_listView->setCurrentItem(lvitem); } - DEBUG(DBG_SRC) << view->umlScene(); + DEBUG(DBG_SRC) << "Changed view to" << view->umlScene(); } /** @@ -3051,7 +3156,7 @@ } /** - * Redo last 'undoed' command. Is called from popupmenu of a view. + * Redo last 'undone' command. Is called from popupmenu of a view. */ void UMLApp::redo() { @@ -3072,7 +3177,7 @@ } /** - * Execute a command and pushit in the stack. + * Execute a command and push it in the stack. */ void UMLApp::executeCommand(QUndoCommand* cmd) { @@ -3085,6 +3190,8 @@ } else { cmd->redo(); } + + m_doc->setModified(true); } /** diff -Nru umbrello-4.12.3/umbrello/umldoc.cpp umbrello-4.12.90/umbrello/umldoc.cpp --- umbrello-4.12.3/umbrello/umldoc.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/umldoc.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -536,6 +536,13 @@ } if (filetype.endsWith(QLatin1String(".mdl"))) { status = Import_Rose::loadFromMDL(file); + if (status) { + QString name = createDiagramName(Uml::DiagramType::Class, false); + createDiagram(m_root[Uml::ModelType::Logical], Uml::DiagramType::Class, name); + m_pCurrentRoot = m_root[Uml::ModelType::Logical]; + } + else + newDocument(); } else { status = loadFromXMI(file, ENC_UNKNOWN); @@ -1298,24 +1305,30 @@ * @param type the type of diagram to create * @param name if true shows a dialog box asking for name, * else uses a default name + * @param id optional ID of new diagram * @return pointer to the UMLView of the new diagram */ -UMLView* UMLDoc::createDiagram(UMLFolder *folder, Uml::DiagramType::Enum type, const QString& name) +UMLView* UMLDoc::createDiagram(UMLFolder *folder, Uml::DiagramType::Enum type, const QString& name, Uml::ID::Type id) { DEBUG(DBG_SRC) << "folder=" << folder->name() << " / type=" << Uml::DiagramType::toString(type) << " / name=" << name; + + if (id == Uml::ID::None) { + id = UniqueID::gen(); + } + if (name.length() > 0) { UMLView* view = new UMLView(folder); view->umlScene()->setOptionState(Settings::optionState()); view->umlScene()->setName(name); view->umlScene()->setType(type); - view->umlScene()->setID(UniqueID::gen()); + view->umlScene()->setID(id); addView(view); - emit sigDiagramCreated(view->umlScene()->ID()); + emit sigDiagramCreated(id); setModified(true); UMLApp::app()->enablePrint(true); - changeCurrentView(view->umlScene()->ID()); + changeCurrentView(id); return view; } return 0; @@ -1395,7 +1408,7 @@ bool ok = false; UMLClassifier* p = dynamic_cast(o->parent()); if (!p) { - DEBUG(DBG_SRC) << "Can not create object, no parent found."; + DEBUG(DBG_SRC) << "Cannot create object, no parent found."; return; } @@ -1451,29 +1464,51 @@ /** * Deletes a diagram from the current file. * + * Undo command + * * @param id The ID of the diagram to delete. */ void UMLDoc::removeDiagram(Uml::ID::Type id) { + UMLView* umlView = findView(id); + if (!umlView) { + uError() << "Request to remove diagram " << Uml::ID::toString(id) << ": Diagram not found!"; + return; + } + + UMLScene* umlScene = umlView->umlScene(); + if (KMessageBox::warningContinueCancel( + 0, + i18n("Are you sure you want to delete diagram %1?", umlScene->name()), + i18n("Delete Diagram"), + KGuiItem(i18n("&Delete"), "edit-delete")) == KMessageBox::Continue + ) { + UMLApp::app()->executeCommand(new Uml::CmdRemoveDiagram( + umlScene->folder(), + umlScene->type(), + umlScene->name(), + id + )); + } +} + +/** + * Deletes a diagram from the current file. + * + * @param id The ID of the diagram to delete. + */ +void UMLDoc::removeDiagramCmd(Uml::ID::Type id) +{ UMLApp::app()->docWindow()->updateDocumentation(true); UMLView* umlview = findView(id); if (!umlview) { uError() << "Request to remove diagram " << Uml::ID::toString(id) << ": Diagram not found!"; return; } - if (KMessageBox::warningContinueCancel(0, i18n("Are you sure you want to delete diagram %1?", - umlview->umlScene()->name()), i18n("Delete Diagram"), - KGuiItem(i18n("&Delete"), "edit-delete")) == KMessageBox::Continue) { - removeView(umlview); - emit sigDiagramRemoved(id); - setModified(true); - /* if (infoWidget->isVisible()) { - emit sigDiagramChanged(Uml::DiagramType::Undefined); - UMLApp::app()->enablePrint(false); - } - */ //FIXME sort out all the KActions for when there's no diagram - //also remove the buttons from the WorkToolBar, then get rid of infowidget - } + + removeView(umlview); + emit sigDiagramRemoved(id); + setModified(true); } /** @@ -1806,7 +1841,7 @@ int line; QDomDocument doc; if (!doc.setContent(data, false, &error, &line)) { - uWarning() << "Can not set content: " << error << " Line: " << line; + uWarning() << "Cannot set content: " << error << " Line: " << line; return ENC_UNKNOWN; } @@ -1897,7 +1932,7 @@ int line; QDomDocument doc; if (!doc.setContent(data, false, &error, &line)) { - uWarning() << "Can not set content:" << error << " Line:" << line; + uWarning() << "Cannot set content:" << error << " Line:" << line; return false; } qApp->processEvents(); // give UI events a chance @@ -2041,9 +2076,7 @@ } } } -#ifdef VERBOSE_DEBUGGING - DEBUG(DBG_SRC) << "m_objectList.count() is " << m_objectList.count(); -#endif + resolveTypes(); // set a default code generator if no tag seen if (UMLApp::app()->generator() == 0) { @@ -2083,8 +2116,8 @@ for (int i = 0; i < Uml::ModelType::N_MODELTYPES; ++i) { UMLFolder *obj = m_root[i]; #ifdef VERBOSE_DEBUGGING - DEBUG(DBG_SRC) << "UMLDoc: invoking resolveRef() for " << obj->getName() - << " (id=" << Uml::ID::toString(obj->ID()) << ")"; + DEBUG(DBG_SRC) << "UMLDoc: invoking resolveRef() for " << obj->name() + << " (id=" << Uml::ID::toString(obj->id()) << ")"; #endif obj->resolveRef(); } @@ -2778,6 +2811,8 @@ return false; } + Uml::ID::Type oldID = pView->umlScene()->ID(); + int i = 0; QString viewName = pView->umlScene()->name(); QString name = viewName; @@ -2787,13 +2822,17 @@ if (i) { //If name was modified pView->umlScene()->setName(name); } - Uml::ID::Type result = assignNewID(pView->umlScene()->ID()); - pView->umlScene()->setID(result); + + Uml::ID::Type newID = assignNewID(oldID); + pView->umlScene()->setID(newID); pView->umlScene()->activateAfterLoad(true); pView->umlScene()->endPartialWidgetPaste(); pView->umlScene()->setOptionState(Settings::optionState()); addView(pView); + + emit sigDiagramCreated(pView->umlScene()->ID()); + setModified(true); return true; } diff -Nru umbrello-4.12.3/umbrello/umldoc.h umbrello-4.12.90/umbrello/umldoc.h --- umbrello-4.12.3/umbrello/umldoc.h 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/umldoc.h 2014-03-05 15:04:09.000000000 +0000 @@ -107,8 +107,13 @@ bool *swap = 0); QString createDiagramName(Uml::DiagramType::Enum type, bool askForName = true); - UMLView* createDiagram(UMLFolder *folder, Uml::DiagramType::Enum type, const QString& name); + UMLView* createDiagram(UMLFolder *folder, + Uml::DiagramType::Enum type, + const QString& name, + Uml::ID::Type id = Uml::ID::None); + void removeDiagram(Uml::ID::Type id); + void removeDiagramCmd(Uml::ID::Type id); void renameDiagram(Uml::ID::Type id); void removeUMLObject(UMLObject* umlobject); diff -Nru umbrello-4.12.3/umbrello/uml.h umbrello-4.12.90/umbrello/uml.h --- umbrello-4.12.3/umbrello/uml.h 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/uml.h 2014-03-05 15:04:09.000000000 +0000 @@ -58,6 +58,7 @@ class QUndoView; class QPushButton; class QLabel; +class QListWidget; class QSlider; /** @@ -96,6 +97,8 @@ UMLListView* listView() const; WorkToolBar* workToolBar() const; DocWindow * docWindow() const; + QListWidget *logWindow() const; + void setModified(bool _m); @@ -166,6 +169,7 @@ QString activeLanguageScopeSeparator(); KConfig* config(); + void importFiles(QStringList* fileList); protected: virtual void keyPressEvent(QKeyEvent* e); @@ -232,10 +236,14 @@ void slotCopyChanged(); void slotPrefs(); void slotApplyPrefs(); + void slotImportClass(); + void slotImportProject(); void slotUpdateViews(); void slotShowTreeView(bool state); + void slotShowDebugView(bool state); void slotShowDocumentationView(bool state); void slotShowCmdHistoryView(bool state); + void slotShowLogView(bool state); void slotCurrentViewClearDiagram(); void slotCurrentViewToggleSnapToGrid(); void slotCurrentViewToggleShowGrid(); @@ -314,8 +322,6 @@ void initClip(); void initSavedCodeGenerators(); - void importFiles(QStringList* fileList); - void createDiagram(Uml::DiagramType::Enum type); QMenu* m_langSelect; ///< For selecting the active language. @@ -348,11 +354,14 @@ QDockWidget* m_mainDock; ///< The widget which shows the diagrams. QDockWidget* m_listDock; ///< Contains the UMLListView tree view. + QDockWidget* m_debugDock; ///< Contains the debug DocWindow widget. QDockWidget* m_documentationDock; ///< Contains the documentation DocWindow widget. QDockWidget* m_cmdHistoryDock; ///< Contains the undo/redo viewer widget. QDockWidget* m_propertyDock; ///< Contains the property browser widget. + QDockWidget* m_logDock; ///< Contains the log window widget. DocWindow* m_docWindow; ///< Documentation window. + QListWidget* m_logWindow; ///< Logging window. QUndoView* m_pQUndoView; ///< Undo / Redo Viewer RefactoringAssistant* m_refactoringAssist; ///< Refactoring assistant. @@ -367,7 +376,9 @@ QAction* editRedo; QAction* viewShowTree; + QAction* viewShowDebug; QAction* viewShowDoc; + QAction* viewShowLog; QAction* viewShowCmdHistory; KActionMenu* newDiagram; diff -Nru umbrello-4.12.3/umbrello/umllistview.cpp umbrello-4.12.90/umbrello/umllistview.cpp --- umbrello-4.12.3/umbrello/umllistview.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/umllistview.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -14,6 +14,7 @@ // app includes #include "actor.h" #include "classifier.h" +#include "cmds.h" #include "debug_utils.h" #include "package.h" #include "folder.h" @@ -35,6 +36,7 @@ #include "foreignkeyconstraint.h" #include "checkconstraint.h" #include "uml.h" +#include "umlclipboard.h" #include "umldoc.h" #include "umllistviewitemlist.h" #include "umllistviewitem.h" @@ -54,6 +56,7 @@ #include "umluniqueconstraintdialog.h" #include "umlforeignkeyconstraintdialog.h" #include "umlcheckconstraintdialog.h" +#include "object_factory.h" // kde includes #include @@ -89,7 +92,8 @@ m_bStartedCut(false), m_bStartedCopy(false), m_bCreatingChildObject(false), - m_dragStartPosition(QPoint()) + m_dragStartPosition(QPoint()), + m_dragCopyData(0) { // setup list view setAcceptDrops(true); @@ -146,7 +150,7 @@ { UMLListViewItem* currItem = static_cast(currentItem()); if (currItem && currItem->isSelected()) { - DEBUG(DBG_SRC) << currItem->text(0); + DEBUG(DBG_SRC) << "UMLListView selection changed to" << currItem->text(0); // Update current view to selected object's view if (Model_Utils::typeIsDiagram(currItem->type())) { // If the user navigates to a diagram, load the diagram just like what @@ -197,10 +201,10 @@ // Get the UMLListViewItem at the point where the mouse pointer was pressed UMLListViewItem * item = static_cast(itemAt(me->pos())); if (item) { - DEBUG(DBG_SRC) << UMLListViewItem::toString(item->type()); + DEBUG(DBG_SRC) << "QMouseEvent on" << UMLListViewItem::toString(item->type()); } else { - DEBUG(DBG_SRC) << "item is NULL"; + DEBUG(DBG_SRC) << "QMouseEvent on empty space"; } const Qt::MouseButton button = me->button(); @@ -240,9 +244,21 @@ } DEBUG(DBG_SRC) << "initiating drag"; + + // Store a copy of selected list items in case the user + // will ctrl-drag (basically just copy/paste) an item + // + // The QDrag mime data is used for moving items onto the diagram + // or internally in the tree view + UMLClipboard clipboard; + if ((m_dragCopyData = clipboard.copy(false)) == 0) { + // This should never happen, this is just like using ctrl+c on the list view item + uError() << "Unable to obtain mime data for copy-drag operation"; + } + QDrag* drag = new QDrag(this); drag->setMimeData(getDragData()); - drag->exec(Qt::CopyAction); + drag->exec(Qt::MoveAction | Qt::CopyAction, Qt::MoveAction); } /** @@ -414,6 +430,14 @@ addNewItem(currItem, UMLListViewItem::lvt_CheckConstraint); break; + case ListPopupMenu::mt_Import_Class: + UMLApp::app()->slotImportClass(); + break; + + case ListPopupMenu::mt_Import_Project: + UMLApp::app()->slotImportProject(); + break; + case ListPopupMenu::mt_Expand_All: expandAll(currItem); break; @@ -637,25 +661,23 @@ UMLApp::app()->slotEditPaste(); break; + case ListPopupMenu::mt_Clone: + UMLApp::app()->slotEditCopy(); + UMLApp::app()->slotEditPaste(); + break; + + case ListPopupMenu::mt_Undefined: + // We got signalled for a menu action, but that menu action was not + // defined in ListPopupMenu. This is the case for "create diagram" + // actions which are defined and handled in UMLApp. This is fine, + // ignore them without warning. + break; + default: - { - Uml::DiagramType::Enum dt = ListPopupMenu::convert_MT_DT(menuType); - if (dt == Uml::DiagramType::Undefined) { - uWarning() << "unknown type" << menuType; - } else { - UMLObject* object = currItem->umlObject(); - UMLFolder* f = dynamic_cast(object); - if (f == 0) { - uError() << "menuType=" << menuType - << ": current item's UMLObject is not a UMLFolder"; - } - else { - QString name = m_doc->createDiagramName(dt); - m_doc->createDiagram(f, dt, name); - } - } - } + uError() << "unknown type" << menuType; + break; + }//end switch } @@ -815,8 +837,8 @@ UMLListViewItem* newItem = findUMLObject(object); if (newItem) { - DEBUG(DBG_SRC) << newItem->type(); - DEBUG(DBG_SRC) << object->name() << ", id= " << Uml::ID::toString(object->id()) + DEBUG(DBG_SRC) << object->name() << ", type=" << newItem->type() + << ", id=" << Uml::ID::toString(object->id()) << ": item already exists."; Icon_Utils::IconType icon = Model_Utils::convert_LVT_IT(newItem->type()); newItem->setIcon(icon); @@ -1368,141 +1390,64 @@ */ bool UMLListView::acceptDrag(QDropEvent* event) const { - UMLListViewItem* item = (UMLListViewItem*)itemAt(event->pos()); - if (!item) { + UMLListViewItem* target = (UMLListViewItem*)itemAt(event->pos()); + if (!target) { DEBUG(DBG_SRC) << "itemAt(mouse position) returns 0"; return false; } - ((QTreeWidget*)this)->setCurrentItem((QTreeWidgetItem*)item); - - UMLDragData::LvTypeAndID_List list; - if (! UMLDragData::getClip3TypeAndID(event->mimeData(), list)) { - DEBUG(DBG_SRC) << "UMLDragData::getClip3TypeAndID returns false"; - return false; - } - UMLDragData::LvTypeAndID_It it(list); - UMLDragData::LvTypeAndID * data = 0; - UMLListViewItem::ListViewType dstType = item->type(); - bool accept = true; - while (accept && it.hasNext()) { - data = it.next(); - UMLListViewItem::ListViewType srcType = data->type; - switch (srcType) { - case UMLListViewItem::lvt_Class: - case UMLListViewItem::lvt_Package: - case UMLListViewItem::lvt_Interface: - case UMLListViewItem::lvt_Enum: - if (dstType == UMLListViewItem::lvt_Logical_View || - dstType == UMLListViewItem::lvt_Class || - dstType == UMLListViewItem::lvt_Package) { - accept = !item->isOwnParent(data->id); + bool accept = false; + UMLListViewItem::ListViewType srcType = UMLListViewItem::lvt_Unknown; + UMLListViewItem::ListViewType dstType = UMLListViewItem::lvt_Unknown; + + // Handle different drop actions + switch (event->proposedAction()) { + case Qt::CopyAction: { + // Instead of relying on the current item being the drag source, + // we should use the mime data to obtain the dragged type (or types + // if we implement multiple item selections in tree view) + srcType = static_cast(currentItem())->type(); + dstType = target->type(); + + // Copy of diagrams is not supported + if (Model_Utils::typeIsDiagram(srcType)) { + accept = false; } else { - accept = (dstType == UMLListViewItem::lvt_Logical_Folder); + accept = Model_Utils::typeIsAllowedInType(srcType, dstType); } break; - case UMLListViewItem::lvt_Attribute: - if (dstType == UMLListViewItem::lvt_Class) { - accept = !item->isOwnParent(data->id); - } - break; - case UMLListViewItem::lvt_EntityAttribute: - if (dstType == UMLListViewItem::lvt_Entity) { - accept = !item->isOwnParent(data->id); - } - break; - case UMLListViewItem::lvt_Operation: - if (dstType == UMLListViewItem::lvt_Class || - dstType == UMLListViewItem::lvt_Interface) { - accept = !item->isOwnParent(data->id); - } - break; - case UMLListViewItem::lvt_Datatype: - accept = (dstType == UMLListViewItem::lvt_Logical_Folder || - dstType == UMLListViewItem::lvt_Datatype_Folder || - dstType == UMLListViewItem::lvt_Class || - dstType == UMLListViewItem::lvt_Interface || - dstType == UMLListViewItem::lvt_Package); - break; - case UMLListViewItem::lvt_Class_Diagram: - case UMLListViewItem::lvt_Collaboration_Diagram: - case UMLListViewItem::lvt_State_Diagram: - case UMLListViewItem::lvt_Activity_Diagram: - case UMLListViewItem::lvt_Sequence_Diagram: - accept = (dstType == UMLListViewItem::lvt_Logical_Folder || - dstType == UMLListViewItem::lvt_Logical_View); - break; - case UMLListViewItem::lvt_Logical_Folder: - if (dstType == UMLListViewItem::lvt_Logical_Folder) { - accept = !item->isOwnParent(data->id); - } else { - accept = (dstType == UMLListViewItem::lvt_Logical_View); - } - break; - case UMLListViewItem::lvt_UseCase_Folder: - if (dstType == UMLListViewItem::lvt_UseCase_Folder) { - accept = !item->isOwnParent(data->id); - } else { - accept = (dstType == UMLListViewItem::lvt_UseCase_View); - } - break; - case UMLListViewItem::lvt_Component_Folder: - if (dstType == UMLListViewItem::lvt_Component_Folder) { - accept = !item->isOwnParent(data->id); - } else { - accept = (dstType == UMLListViewItem::lvt_Component_View); - } - break; - case UMLListViewItem::lvt_Deployment_Folder: - if (dstType == UMLListViewItem::lvt_Deployment_Folder) { - accept = !item->isOwnParent(data->id); - } else { - accept = (dstType == UMLListViewItem::lvt_Deployment_View); + } + case Qt::MoveAction: { + UMLDragData::LvTypeAndID_List list; + if (!UMLDragData::getClip3TypeAndID(event->mimeData(), list)) { + uError() << "UMLDragData::getClip3TypeAndID returns false"; + return false; } - break; - case UMLListViewItem::lvt_EntityRelationship_Folder: - if (dstType == UMLListViewItem::lvt_EntityRelationship_Folder) { - accept = !item->isOwnParent(data->id); - } else { - accept = (dstType == UMLListViewItem::lvt_EntityRelationship_Model); + + UMLDragData::LvTypeAndID_It it(list); + UMLDragData::LvTypeAndID * data = 0; + dstType = target->type(); + while (it.hasNext()) { + data = it.next(); + srcType = data->type; + accept = Model_Utils::typeIsAllowedInType(srcType, dstType); + + // disallow drop of any child element is not allowed + if (!accept) break; } break; - case UMLListViewItem::lvt_Actor: - case UMLListViewItem::lvt_UseCase: - case UMLListViewItem::lvt_UseCase_Diagram: - accept = (dstType == UMLListViewItem::lvt_UseCase_Folder || - dstType == UMLListViewItem::lvt_UseCase_View); - break; - case UMLListViewItem::lvt_Subsystem: - accept = (dstType == UMLListViewItem::lvt_Component_Folder || - dstType == UMLListViewItem::lvt_Subsystem); - break; - case UMLListViewItem::lvt_Component: - accept = (dstType == UMLListViewItem::lvt_Component_Folder || - dstType == UMLListViewItem::lvt_Component || - dstType == UMLListViewItem::lvt_Subsystem); - break; - case UMLListViewItem::lvt_Artifact: - case UMLListViewItem::lvt_Component_Diagram: - accept = (dstType == UMLListViewItem::lvt_Component_Folder || - dstType == UMLListViewItem::lvt_Component_View); - break; - case UMLListViewItem::lvt_Node: - case UMLListViewItem::lvt_Deployment_Diagram: - accept = (dstType == UMLListViewItem::lvt_Deployment_Folder); - break; - case UMLListViewItem::lvt_Entity: - case UMLListViewItem::lvt_EntityRelationship_Diagram: - case UMLListViewItem::lvt_Category: - accept = (dstType == UMLListViewItem::lvt_EntityRelationship_Folder); - break; - default: - accept = false; - break; } + default: { + uError() << "Unsupported drop-action in acceptDrag()"; + return false; + } + } + + if (!accept) { + uDebug() << "Disallowing drop because source type" << UMLListViewItem::toString(srcType) + << "is not allowed in target type" << UMLListViewItem::toString(dstType); } - DEBUG(DBG_SRC) << "dstType = " << dstType << ", accept=" << accept; return accept; } @@ -1569,7 +1514,7 @@ } UMLListViewItem::ListViewType newParentType = newParent->type(); - DEBUG(DBG_SRC) << "newParentType is " << newParentType; + DEBUG(DBG_SRC) << "newParentType is " << UMLListViewItem::toString(newParentType); UMLListViewItem *newItem = 0; //make sure trying to place in correct location @@ -1795,25 +1740,33 @@ /** * Something has been dragged and dropped onto the list view. */ -void UMLListView::slotDropped(QDropEvent* de, UMLListViewItem* parent, UMLListViewItem* item) +void UMLListView::slotDropped(QDropEvent* de, UMLListViewItem* target) { - Q_UNUSED(parent); - item = (UMLListViewItem *)currentItem(); - if (!item) { - DEBUG(DBG_SRC) << "item is 0 - doing nothing"; - return; - } - UMLDragData::LvTypeAndID_List srcList; - if (! UMLDragData::getClip3TypeAndID(de->mimeData(), srcList)) { - return; - } - UMLListViewItem *newParent = (UMLListViewItem*)item; - DEBUG(DBG_SRC) << "slotDropped: newParent->text(0) is " << newParent->text(0); - UMLDragData::LvTypeAndID_It it(srcList); - UMLDragData::LvTypeAndID * src = 0; - while (it.hasNext()) { - src = it.next(); - moveObject(src->id, src->type, newParent); + DEBUG(DBG_SRC) << "Dropping on target " << target->text(0); + + // Copy or move tree items + if (de->dropAction() == Qt::CopyAction) { + UMLClipboard clipboard; + + // Todo: refactor UMLClipboard to support pasting to a non-current item + setCurrentItem(target); + + // Paste the data (not always clip3) + if (!clipboard.paste(m_dragCopyData)) { + uError() << "Unable to copy selected item into the target item"; + } + } else { + UMLDragData::LvTypeAndID_List srcList; + if (! UMLDragData::getClip3TypeAndID(de->mimeData(), srcList)) { + uError() << "Unexpected mime data in drop event"; + return; + } + UMLDragData::LvTypeAndID_It it(srcList); + UMLDragData::LvTypeAndID * src = 0; + while (it.hasNext()) { + src = it.next(); + moveObject(src->id, src->type, target); + } } } @@ -2082,448 +2035,57 @@ */ void UMLListView::addNewItem(UMLListViewItem *parentItem, UMLListViewItem::ListViewType type) { - UMLListViewItem *newItem; if (type == UMLListViewItem::lvt_Datatype) { parentItem = m_datatypeFolder; } - blockSignals(true); parentItem->setOpen(true); - Icon_Utils::IconType icon = Model_Utils::convert_LVT_IT(type); - - QString name; - if (Model_Utils::typeIsDiagram(type)) { - Uml::DiagramType::Enum dt = Model_Utils::convert_LVT_DT(type); - name = uniqueDiagramName(dt); - newItem = new UMLListViewItem(parentItem, name, type, Uml::ID::None); - } else { - UMLObject::ObjectType ot = Model_Utils::convert_LVT_OT(type); - if (ot == UMLObject::ot_UMLObject) { - DEBUG(DBG_SRC) << "no UMLObject for type " << UMLListViewItem::toString(type); - return; - } - UMLPackage *parentPkg = - dynamic_cast(parentItem->umlObject()); - if (parentPkg == 0) { - uError() << "UMLListView::addNewItem - " - << UMLListViewItem::toString(type) << ": parentPkg is 0"; - return; - } - if (Model_Utils::typeIsClassifierList(type)) { - UMLClassifier *parent = static_cast(parentPkg); - name = parent->uniqChildName(ot); - } else { - name = Model_Utils::uniqObjectName(ot, parentPkg); - } - newItem = new UMLListViewItem(parentItem, name, type, (UMLObject *)0); + // Determine the UMLObject belonging to the listview item we're using as parent + UMLObject* parent = parentItem->umlObject(); + if (parent == 0) { + uError() << "UMLListView::addNewItem - " + << UMLListViewItem::toString(type) << ": parentPkg is 0"; + return; } - newItem->setIcon(icon); - newItem->setOpen(true); - blockSignals(false); - createItem(newItem); -} -/** - * Called for informing the list view that an item was renamed. - */ -bool UMLListView::itemRenamed(UMLListViewItem * item, int col) -{ - DEBUG(DBG_SRC) << item->text(col); - UMLListViewItem * renamedItem = static_cast< UMLListViewItem *>(item) ; - UMLListViewItem::ListViewType type = renamedItem->type(); - QString newText = renamedItem->text(col); - - // If the type is empty then delete it. - if (newText.isEmpty() || newText.contains(QRegExp("^\\s+$"))) { - KMessageBox::error( - 0, - i18n("The name you entered was invalid.\nCreation process has been canceled."), - i18n("Name Not Valid")); - return false; + // Determine the ObjectType of the new object + UMLObject::ObjectType objectType = Model_Utils::convert_LVT_OT(type); + if (objectType == UMLObject::ot_UMLObject) { + uError() << "no UMLObject for type " << UMLListViewItem::toString(type); + return; } - if (!isUnique(renamedItem, newText)) { - //if operation ask if ok not to be unique i.e overloading - if (type == UMLListViewItem::lvt_Operation) { - if (KMessageBox::warningYesNo( - 0, - i18n("The name you entered was not unique.\nIs this what you wanted?"), - i18n("Name Not Unique"), KGuiItem(i18n("Use Name")), KGuiItem(i18n("Enter New Name"))) == KMessageBox::No) { - return false; - } - } else { - KMessageBox::error( - 0, - i18n("The name you entered was not unique.\nCreation process has been canceled."), - i18n("Name Not Unique")); - return false; - } - } - return createItem(renamedItem); -} + if (Model_Utils::typeIsClassifierList(type)) { + UMLClassifier* classifier = dynamic_cast(parent); + QString name = classifier->uniqChildName(objectType); + UMLObject* object = Object_Factory::createChildObject(classifier, objectType, name); -bool UMLListView::createItem(UMLListViewItem *item) -{ - const UMLListViewItem::ListViewType type = item->type(); - switch (type) { - case UMLListViewItem::lvt_Actor: - case UMLListViewItem::lvt_Class: - case UMLListViewItem::lvt_Package: - case UMLListViewItem::lvt_Logical_Folder: - case UMLListViewItem::lvt_UseCase_Folder: - case UMLListViewItem::lvt_Component_Folder: - case UMLListViewItem::lvt_Deployment_Folder: - case UMLListViewItem::lvt_EntityRelationship_Folder: - case UMLListViewItem::lvt_Subsystem: - case UMLListViewItem::lvt_Component: - case UMLListViewItem::lvt_Node: - case UMLListViewItem::lvt_Artifact: - case UMLListViewItem::lvt_Interface: - case UMLListViewItem::lvt_Datatype: - case UMLListViewItem::lvt_Enum: - case UMLListViewItem::lvt_Entity: - case UMLListViewItem::lvt_UseCase: - case UMLListViewItem::lvt_Category: { - UMLObject::ObjectType ot = Model_Utils::convert_LVT_OT(type); - if (! ot) { - uError() << "internal error"; - return false; + // Handle primary key constraints (mark the unique constraint as PK on + // the parent entity) + if (type == UMLListViewItem::lvt_PrimaryKeyConstraint) { + UMLUniqueConstraint* uuc = static_cast(object); + UMLEntity* ent = static_cast(uuc->parent()); + if (ent) { + ent->setAsPrimaryKey(uuc); + } } - UMLObject *o = createUMLObject(item, ot); - if (type == UMLListViewItem::lvt_Subsystem) - o->setStereotype("subsystem"); - else if (Model_Utils::typeIsFolder(type)) - o->setStereotype("folder"); - } - break; - - case UMLListViewItem::lvt_Attribute: - case UMLListViewItem::lvt_EntityAttribute: - case UMLListViewItem::lvt_Operation: - case UMLListViewItem::lvt_Template: - case UMLListViewItem::lvt_EnumLiteral: - case UMLListViewItem::lvt_UniqueConstraint: - case UMLListViewItem::lvt_ForeignKeyConstraint: - case UMLListViewItem::lvt_CheckConstraint: - return createChildUMLObject(item, Model_Utils::convert_LVT_OT(type)); - break; - - case UMLListViewItem::lvt_PrimaryKeyConstraint: { - bool result = createChildUMLObject(item, Model_Utils::convert_LVT_OT(type)); - UMLObject* obj = item->umlObject(); - UMLUniqueConstraint* uuc = static_cast(obj); - UMLEntity* ent = static_cast(uuc->parent()); - if (ent) - ent->setAsPrimaryKey(uuc); - - return result; - } - break; - - case UMLListViewItem::lvt_Class_Diagram: - createDiagram(item, Uml::DiagramType::Class); - break; - - case UMLListViewItem::lvt_UseCase_Diagram: - createDiagram(item, Uml::DiagramType::UseCase); - break; - - case UMLListViewItem::lvt_Sequence_Diagram: - createDiagram(item, Uml::DiagramType::Sequence); - break; - - case UMLListViewItem::lvt_Collaboration_Diagram: - createDiagram(item, Uml::DiagramType::Collaboration); - break; - - case UMLListViewItem::lvt_State_Diagram: - createDiagram(item, Uml::DiagramType::State); - break; - - case UMLListViewItem::lvt_Activity_Diagram: - createDiagram(item, Uml::DiagramType::Activity); - break; - - case UMLListViewItem::lvt_Component_Diagram: - createDiagram(item, Uml::DiagramType::Component); - break; - - case UMLListViewItem::lvt_Deployment_Diagram: - createDiagram(item, Uml::DiagramType::Deployment); - break; - - case UMLListViewItem::lvt_EntityRelationship_Diagram: - createDiagram(item, Uml::DiagramType::EntityRelationship); - break; - - default: - break; - } - return true; -} - -/** - * Creates a UMLObject out of the given list view item. - */ -UMLObject *UMLListView::createUMLObject(UMLListViewItem * item, UMLObject::ObjectType type) -{ - QString name = item->text(0); - UMLObject * object = 0; - switch (type) { - case UMLObject::ot_UseCase: - object = new UMLUseCase(name); - break; - - case UMLObject::ot_Actor: - object = new UMLActor(name); - break; - - case UMLObject::ot_Class: - object = new UMLClassifier(name); - break; - - case UMLObject::ot_Package: - object = new UMLPackage(name); - break; - - case UMLObject::ot_Folder: - object = new UMLFolder(name); - break; - - case UMLObject::ot_Component: - object = new UMLComponent(name); - break; - - case UMLObject::ot_Node: - object = new UMLNode(name); - break; - - case UMLObject::ot_Artifact: - object = new UMLArtifact(name); - break; - - case UMLObject::ot_Interface: { - UMLClassifier *c = new UMLClassifier(name); - c->setBaseType(UMLObject::ot_Interface); - object = c; - } - break; - - case UMLObject::ot_Datatype: { - UMLClassifier *c = new UMLClassifier(name); - c->setBaseType(UMLObject::ot_Datatype); - object = c; - } - break; - - case UMLObject::ot_Enum: - object = new UMLEnum(name); - break; - - case UMLObject::ot_Entity: - object = new UMLEntity(name); - break; - - case UMLObject::ot_Category: - object = new UMLCategory(name); - break; - - default: - uWarning() << "creating UML Object of unknown type"; - return 0; - } - - UMLListViewItem * parentItem = static_cast(item->parent()); - const UMLListViewItem::ListViewType lvt = parentItem->type(); - if (! Model_Utils::typeIsContainer(lvt)) { - uError() << object->name() << ": parentItem (" << lvt << " is not a container"; - delete object; - return 0; - } - UMLPackage *pkg = static_cast(parentItem->umlObject()); - object->setUMLPackage(pkg); - pkg->addObject(object); - connectNewObjectsSlots(object); - item->setUMLObject(object); - item->setText(name); - return object; -} - -/** - * Creates a child UMLObject out of the given list view item. - */ -bool UMLListView::createChildUMLObject(UMLListViewItem * item, UMLObject::ObjectType type) -{ - m_bCreatingChildObject = true; - QString text = item->text(0); - UMLObject* parent = static_cast(item->parent())->umlObject(); - if (!parent) { - uError() << "parent UMLObject is 0"; - m_bCreatingChildObject = false; - return false; - } + } else { + UMLPackage* package = dynamic_cast(parent); + QString name = Model_Utils::uniqObjectName(objectType, package); + UMLObject* object = Object_Factory::createUMLObject(objectType, name, package); - UMLObject* newObject = 0; - if (type == UMLObject::ot_EnumLiteral) { - UMLEnum *owningEnum = static_cast(parent); - newObject = owningEnum->createEnumLiteral(text); - - UMLEnumLiteral* enumLiteral = static_cast(newObject); - text = enumLiteral->toString(Uml::SignatureType::SigNoVis); - } else if (type == UMLObject::ot_Template) { - UMLClassifier *owningClassifier = static_cast(parent); - Model_Utils::NameAndType nt; - Model_Utils::Parse_Status st = Model_Utils::parseTemplate(text, nt, owningClassifier); - if (st) { - KMessageBox::error(0, - Model_Utils::psText(st), - i18n("Creation canceled")); - m_bCreatingChildObject = false; - return false; - } - newObject = owningClassifier->createTemplate(nt.m_name); - UMLTemplate *tmplParm = static_cast(newObject); - tmplParm->setType(nt.m_type); - text = tmplParm->toString(Uml::SignatureType::SigNoVis); - } else if (type == UMLObject::ot_Attribute || type == UMLObject::ot_EntityAttribute) { - UMLClassifier *owningClass = static_cast(parent); - Model_Utils::NameAndType nt; - Uml::Visibility::Enum vis; - Model_Utils::Parse_Status st; - st = Model_Utils::parseAttribute(text, nt, owningClass, &vis); - if (st) { - KMessageBox::error(0, - Model_Utils::psText(st), - i18n("Creation canceled")); - m_bCreatingChildObject = false; - return false; - } - newObject = owningClass->createAttribute(nt.m_name, nt.m_type, vis, nt.m_initialValue); - UMLAttribute *att = static_cast(newObject); - att->setParmKind(nt.m_direction); - text = att->toString(Uml::SignatureType::SigNoVis); - } else if (type == UMLObject::ot_Operation) { - UMLClassifier *owningClassifier = static_cast(parent); - Model_Utils::OpDescriptor od; - Model_Utils::Parse_Status st = Model_Utils::parseOperation(text, od, owningClassifier); - if (st) { - KMessageBox::error(0, - Model_Utils::psText(st), - i18n("Creation canceled")); - m_bCreatingChildObject = false; - return false; - } - bool isExistingOp = false; - newObject = owningClassifier->createOperation(od.m_name, &isExistingOp, &od.m_args); - if (newObject == 0 || isExistingOp) { - if (isExistingOp) - KMessageBox::error( - 0, - i18n("The name you entered was not unique.\nCreation process has been canceled."), - i18n("Name Not Unique")); - m_bCreatingChildObject = false; - return false; - } - UMLOperation *op = static_cast(newObject); - if (od.m_pReturnType) { - op->setType(od.m_pReturnType); - } - text = op->toString(Uml::SignatureType::SigNoVis); - } else if (type == UMLObject::ot_UniqueConstraint || type == UMLObject::ot_ForeignKeyConstraint - || type == UMLObject::ot_CheckConstraint) { - - UMLEntity *owningEntity = static_cast(parent); - - QString name; - Model_Utils::Parse_Status st = Model_Utils::parseConstraint(text, name, owningEntity); - if (st) { - KMessageBox::error(0, - Model_Utils::psText(st), - i18n("Creation canceled")); - m_bCreatingChildObject = false; - return false; + if (object == 0) { + // creation was cancelled by the user + return; } - switch (type) { - case UMLObject::ot_UniqueConstraint: - newObject = owningEntity->createUniqueConstraint(name); - break; - case UMLObject::ot_ForeignKeyConstraint: - newObject = owningEntity->createForeignKeyConstraint(name); - break; - case UMLObject::ot_CheckConstraint: - newObject = owningEntity->createCheckConstraint(name); - break; - default: - break; + if (type == UMLListViewItem::lvt_Subsystem) { + object->setStereotypeCmd("subsystem"); + } else if (Model_Utils::typeIsFolder(type)) { + object->setStereotypeCmd("folder"); } - - UMLEntityConstraint* uec = static_cast(newObject); - - text = uec->toString(Uml::SignatureType::SigNoVis); - } else { - uError() << "called for type " << type << " (ignored)"; - m_bCreatingChildObject = false; - return false; } - - // make changes to the object visible to this umllistviewitem - connectNewObjectsSlots(newObject); - item->setUMLObject(newObject); - item->setText(text); - scrollToItem(item); - - // as it's a ClassifierListItem add it to the childObjectMap of the parent - UMLClassifierListItem* classifierListItem = static_cast(newObject); - static_cast(item->parent())->addClassifierListItem(classifierListItem, item); - - m_bCreatingChildObject = false; - - if (! m_doc->loading()) - m_doc->setModified(); - return true; -} - -/** - * Creates a diagram out of the given list view item. - */ -UMLView* UMLListView::createDiagram(UMLListViewItem * item, Uml::DiagramType::Enum type) -{ - QString name = item->text(0); - DEBUG(DBG_SRC) << name << " / type=" << Uml::DiagramType::toString(type); - UMLView * view = m_doc->findView(type, name); - if (view) { - delete item; - return view; - } - UMLListViewItem *parentItem = static_cast(item->parent()); - UMLFolder *parentFolder = dynamic_cast(parentItem->umlObject()); - if (parentFolder == 0) { - uError() << name << ": parent UMLObject is not a UMLFolder"; - delete item; - return 0; - } - view = new UMLView(parentFolder); - view->umlScene()->setName(name); - view->umlScene()->setType(type); - view->umlScene()->setID(UniqueID::gen()); - m_doc->addView(view); - view->umlScene()->setOptionState(Settings::optionState()); - item->setID(view->umlScene()->ID()); - item->setText(0, name); - view->umlScene()->activate(); - m_doc->changeCurrentView(view->umlScene()->ID()); - - return view; -} - -/** - * Returns a unique name for a diagram. - */ -QString UMLListView::uniqueDiagramName(Uml::DiagramType::Enum type) -{ - return m_doc->uniqueViewName(type); } /** @@ -3041,7 +2603,8 @@ canvasObj->removeAllChildObjects(); } if (object) { - m_doc->removeUMLObject(object); + UMLApp::app()->executeCommand(new Uml::CmdRemoveUMLObject(object)); + // Physical deletion of `temp' will be done by Qt signal, see // UMLDoc::removeUMLObject() } else { @@ -3054,21 +2617,25 @@ } /** - * + * Always allow starting a drag */ void UMLListView::dragEnterEvent(QDragEnterEvent* event) { event->accept(); - QTreeWidget::dragEnterEvent(event); } /** - * + * Check drag destination and update move/copy action */ void UMLListView::dragMoveEvent(QDragMoveEvent* event) { - event->accept(); - QTreeWidget::dragMoveEvent(event); + // Check if drag destination is compatible with source + if (acceptDrag(event)) { + event->acceptProposedAction(); + } else { + event->ignore(); + return; + } } /** @@ -3080,15 +2647,14 @@ event->ignore(); } else { - UMLListViewItem* item = static_cast(itemAt(event->pos())); - if (!item) { + UMLListViewItem* target = static_cast(itemAt(event->pos())); + if (!target) { DEBUG(DBG_SRC) << "itemAt(mousePoint) returns 0"; event->ignore(); return; } - slotDropped(event, 0, item); + slotDropped(event, target); } - QTreeWidget::dropEvent(event); } void UMLListView::commitData(QWidget *editor) diff -Nru umbrello-4.12.3/umbrello/umllistview.h umbrello-4.12.90/umbrello/umllistview.h --- umbrello-4.12.3/umbrello/umllistview.h 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/umllistview.h 2014-03-05 15:04:09.000000000 +0000 @@ -87,12 +87,6 @@ void changeIconOf(UMLObject *o, Icon_Utils::IconType to); - UMLObject *createUMLObject(UMLListViewItem * item, UMLObject::ObjectType type); - bool createChildUMLObject(UMLListViewItem * item, UMLObject::ObjectType type); - UMLView* createDiagram(UMLListViewItem * item, Uml::DiagramType::Enum type); - - QString uniqueDiagramName(Uml::DiagramType::Enum type); - bool isUnique(UMLListViewItem * item, const QString &name); void setSelected(UMLListViewItem * item, bool state) { setItemSelected((QTreeWidgetItem*)item, state); } @@ -103,8 +97,6 @@ UMLListViewItem * moveObject(Uml::ID::Type srcId, UMLListViewItem::ListViewType srcType, UMLListViewItem *newParent); - bool itemRenamed(UMLListViewItem* item, int col); - void closeDatatypesFolder(); UMLListViewItem *theRootView() { return m_rv; } @@ -167,7 +159,7 @@ void slotMenuSelection(QAction* action); - void slotDropped(QDropEvent* de, UMLListViewItem* parent, UMLListViewItem* item); + void slotDropped(QDropEvent* de, UMLListViewItem* target); void expandAll(UMLListViewItem *item); void collapseAll(UMLListViewItem *item); @@ -194,6 +186,7 @@ bool m_bStartedCopy; bool m_bCreatingChildObject; ///< when creating an attribute or an operation to stop it adding a second listViewItem QPoint m_dragStartPosition; + QMimeData* m_dragCopyData; }; #endif diff -Nru umbrello-4.12.3/umbrello/umllistviewitem.cpp umbrello-4.12.90/umbrello/umllistviewitem.cpp --- umbrello-4.12.3/umbrello/umllistviewitem.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/umllistviewitem.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -355,14 +355,6 @@ else icon = Icon_Utils::it_Package; break; - /* - case UMLObject::ot_Folder: - { - ListViewType lvt = Model_Utils::convert_OT_LVT(m_object); - icon = Model_Utils::convert_LVT_IT(lvt); - } - break; - */ case UMLObject::ot_Operation: if (scope == Uml::Visibility::Public) icon = Icon_Utils::it_Public_Method; diff -Nru umbrello-4.12.3/umbrello/umlobject.cpp umbrello-4.12.90/umbrello/umlobject.cpp --- umbrello-4.12.3/umbrello/umlobject.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/umlobject.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -103,7 +103,6 @@ m_Doc.clear(); m_bAbstract = false; m_bStatic = false; - m_bInPaste = false; m_bCreationWasSignalled = false; m_pSecondary = 0; } @@ -167,7 +166,9 @@ */ void UMLObject::setName(const QString &strName) { - UMLApp::app()->executeCommand(new Uml::CmdRenameUMLObject(this, strName)); + if (name() != strName) { + UMLApp::app()->executeCommand(new Uml::CmdRenameUMLObject(this, strName)); + } } /** @@ -323,11 +324,6 @@ emitModified(); } -void UMLObject::setInPaste(bool bInPaste /* =true */) -{ - m_bInPaste = bInPaste; -} - /** * Returns true if this UMLObject has classifier scope, * otherwise false (the default). @@ -444,7 +440,9 @@ */ void UMLObject::setVisibility(Visibility::Enum visibility) { - UMLApp::app()->executeCommand(new CmdSetVisibility(this, visibility)); + if (m_visibility != visibility) { + UMLApp::app()->executeCommand(new CmdSetVisibility(this, visibility)); + } } /** @@ -489,26 +487,26 @@ * Sets the classes stereotype name. * Internally uses setUMLStereotype(). * - * @param _name Sets the classes stereotype name. + * @param name Sets the classes stereotype name. */ -void UMLObject::setStereotype(const QString &_name) +void UMLObject::setStereotype(const QString &name) { - // UMLDoc* pDoc = UMLApp::app()->document(); - // pDoc->executeCommand(new cmdSetStereotype(this, _name)); - if (_name.isEmpty()) { + if (name != stereotype()) { + UMLApp::app()->executeCommand(new CmdSetStereotype(this, name)); + } +} + +void UMLObject::setStereotypeCmd(const QString& name) +{ + if (name.isEmpty()) { setUMLStereotype(NULL); return; } UMLDoc *pDoc = UMLApp::app()->document(); - UMLStereotype *s = pDoc->findOrCreateStereotype(_name); + UMLStereotype *s = pDoc->findOrCreateStereotype(name); setUMLStereotype(s); } -void UMLObject::setStereotypeCmd(const QString& /*_name*/) -{ -//TODO: put SetStereotype into QundoStack -} - /** * Sets the classes Package. * DEPRECATED - use SetUMLPackage instead. @@ -996,7 +994,7 @@ } else { uDebug() << m_name << ": UMLStereotype " << Uml::ID::toString(stereoID) << " not found, creating now."; - setStereotype(stereo); + setStereotypeCmd(stereo); } } @@ -1066,15 +1064,6 @@ m_BaseType != ot_Template && m_BaseType != ot_Stereotype && m_BaseType != ot_Role && m_BaseType != ot_UniqueConstraint && m_BaseType != ot_ForeignKeyConstraint) { - // Todo: refactor outside of loadFromXmi() - // - // Determine parent of new object: - // * if m_bInPaste=true, object was pasted in the tree view -> get package from current - // * if there's no package and we're not loading a XMI file, object was - // pasted from another instance of umbrello -> get package from current - if (m_bInPaste || (!m_pUMLPackage && !umldoc->loading())) { - m_pUMLPackage = Model_Utils::treeViewGetPackageFromCurrent(); - } if (m_pUMLPackage) { m_pUMLPackage->addObject(this); } else if (umldoc->rootFolderType(this) == Uml::ModelType::N_MODELTYPES) { diff -Nru umbrello-4.12.3/umbrello/umlobject.h umbrello-4.12.90/umbrello/umlobject.h --- umbrello-4.12.3/umbrello/umlobject.h 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/umlobject.h 2014-03-05 15:04:09.000000000 +0000 @@ -128,8 +128,6 @@ void setAbstract(bool bAbstract); bool isAbstract() const; - void setInPaste(bool bInPaste = true); - // FIXME: merge with showPropertiesDialog() virtual bool showPropertiesPagedDialog(int page = 0, bool assoc = false); diff -Nru umbrello-4.12.3/umbrello/umlscene.cpp umbrello-4.12.90/umbrello/umlscene.cpp --- umbrello-4.12.3/umbrello/umlscene.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/umlscene.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -51,8 +51,8 @@ #include "seqlinewidget.h" #include "signalwidget.h" #include "statewidget.h" -#include "toolbarstatefactory.h" #include "toolbarstate.h" +#include "toolbarstatefactory.h" #include "uml.h" #include "umldoc.h" #include "umldragdata.h" @@ -511,16 +511,18 @@ */ void UMLScene::setupNewWidget(UMLWidget *w) { - w->setX(m_Pos.x()); - w->setY(m_Pos.y()); + // Objects position is handled inside the widget + if (w->baseType() != WidgetBase::wt_Object) { + w->setX(m_Pos.x()); + w->setY(m_Pos.y()); + } w->setVisible(true); - w->setActivated(); - w->setFont(font()); + w->activate(); + w->setFontCmd(font()); w->slotFillColorChanged(ID()); w->slotTextColorChanged(ID()); w->slotLineWidthChanged(ID()); resizeSceneToItems(); - m_WidgetList.append(w); m_doc->setModified(); UMLApp::app()->executeCommand(new CmdCreateWidget(w)); @@ -601,15 +603,7 @@ return; } - newWidget->setActivated(); - newWidget->setFont(font()); - newWidget->slotFillColorChanged(ID()); - newWidget->slotTextColorChanged(ID()); - newWidget->slotLineWidthChanged(ID()); - newWidget->updateGeometry(); - - m_WidgetList.append(newWidget); - newWidget->activate(); + setupNewWidget(newWidget); m_bCreateObject = false; @@ -813,12 +807,15 @@ DEBUG(DBG_SRC) << "object id=" << Uml::ID::toString(id) << " not found"; return; } - m_bCreateObject = true; + m_Pos = e->scenePos(); - slotObjectCreated(o); + UMLWidget* newWidget = Widget_Factory::createWidget(this, o); + if (!newWidget) { + return; + } - m_doc->setModified(true); + setupNewWidget(newWidget); } /** @@ -879,14 +876,13 @@ void UMLScene::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event) { m_pToolBarState->mouseDoubleClick(event); - - if (!onItem(event->scenePos())) { + if (!event->isAccepted()) { // show properties dialog of the scene if (m_view->showPropDialog() == true) { m_doc->setModified(); } + event->accept(); } - event->accept(); } /** @@ -953,9 +949,9 @@ */ UMLWidget* UMLScene::getFirstMultiSelectedWidget() const { - if (m_selectedList.size() == 0) + if (selectedWidgets().size() == 0) return 0; - return m_selectedList.first(); + return selectedWidgets().first(); } /** @@ -1022,18 +1018,10 @@ return; } - MessageWidgetListIt it(m_MessageList); foreach(MessageWidget *obj, m_MessageList) { - if (! obj->hasObjectWidget(w)) { - continue; + if (obj->hasObjectWidget(w)) { + removeWidget(obj); } - //make sure message doesn't have any associations - removeAssociations(obj); - obj->cleanup(); - //make sure not in selected list - m_selectedList.removeAll(obj); - m_MessageList.removeAll(obj); - obj->deleteLater(); } } @@ -1087,6 +1075,29 @@ } /** + * Finds a widget with the given local ID. + * @param id The ID of the widget to find. + * + * @return Returns the widget found, returns 0 if no widget found. + */ +UMLWidget * UMLScene::findWidgetByLocalId(Uml::ID::Type id) +{ + foreach(UMLWidget* obj, m_WidgetList) { + if (obj->localID() == id) { + return obj; + } + } + + foreach(UMLWidget* obj, m_MessageList) { + if (obj->localID() == id) { + return obj; + } + } + + return 0; +} + +/** * Finds an association widget with the given ID. * * @param id The ID of the widget to find. @@ -1165,12 +1176,22 @@ } /** - * Remove a widget from view. + * Remove a widget from view (undo command) * * @param o The widget to remove. */ void UMLScene::removeWidget(UMLWidget * o) { + UMLApp::app()->executeCommand(new CmdRemoveWidget(o)); +} + +/** + * Remove a widget from view. + * + * @param o The widget to remove. + */ +void UMLScene::removeWidgetCmd(UMLWidget * o) +{ if (!o) return; @@ -1184,7 +1205,7 @@ } o->cleanup(); - m_selectedList.removeAll(o); + o->setSelectedFlag(false); disconnect(this, SIGNAL(sigClearAllSelected()), o, SLOT(slotClearAllSelected())); disconnect(this, SIGNAL(sigFillColorChanged(Uml::ID::Type)), o, SLOT(slotFillColorChanged(Uml::ID::Type))); disconnect(this, SIGNAL(sigLineColorChanged(Uml::ID::Type)), o, SLOT(slotLineColorChanged(Uml::ID::Type))); @@ -1224,65 +1245,20 @@ } /** - * Check if at the given point is a widget or an association widget. - * @param atPos the mouse position on the scene - * @return true if there is a widget or an association line - */ -bool UMLScene::onItem(const QPointF& atPos) -{ - UMLWidget* widget = widgetAt(atPos); - if (widget) { - DEBUG(DBG_SRC) << "uml widget = " << widget->name() << " / type = " << widget->baseTypeStr(); - return true; - } - - AssociationWidget* association = associationAt(atPos); - if (association) { - DEBUG(DBG_SRC) << "association = " << association->name() << " / type = " << association->baseTypeStr(); - return true; - } - - MessageWidget* message = messageAt(atPos); - if (message) { - DEBUG(DBG_SRC) << "message = " << message->name() << " / type = " << message->baseTypeStr(); - return true; - } - - DEBUG(DBG_SRC) << "Not on any item!"; - return false; -} - -/** - * Sets a widget to a selected state and adds it to a list of selected widgets. - * This method also sets the state of the cut and copy menu entries. - * - * @param w The widget to set to selected. - * @param me The mouse event containing the information about the selection. - */ -void UMLScene::setSelected(UMLWidget *w, QGraphicsSceneMouseEvent *me) -{ - Q_UNUSED(me); - //only add if wasn't in list - if (!m_selectedList.removeAll(w)) - m_selectedList.append(w); - int count = m_selectedList.count(); - //only call once - if we select more, no need to keep clearing window - - // if count == 1, widget will update the doc window with their data when selected - if (count == 2) - UMLApp::app()->docWindow()->updateDocumentation(true); //clear doc window - - // selection changed, we have to make sure the copy and paste items - // are correctly enabled/disabled - UMLApp::app()->slotCopyChanged(); -} - -/** * Returns a list of selected widgets. + * QGraphicsScene calls widgets isSelected() to determine selection state. */ UMLWidgetList UMLScene::selectedWidgets() const { - return m_selectedList; + QList items = selectedItems(); + + UMLWidgetList widgets; + foreach(QGraphicsItem *item, items) { + UMLWidget *w = dynamic_cast(item); + if (w) + widgets.append(w); + } + return widgets; } /** @@ -1290,7 +1266,7 @@ */ void UMLScene::clearSelected() { - m_selectedList.clear(); + clearSelection(); emit sigClearAllSelected(); //m_doc->enableCutCopy(false); } @@ -1317,9 +1293,17 @@ */ void UMLScene::selectionUseFillColor(bool useFC) { + if (useFC) { + UMLApp::app()->beginMacro(i18n("Use fill color")); + } else { + UMLApp::app()->beginMacro(i18n("No fill color")); + } + foreach(UMLWidget* widget, selectedWidgets()) { widget->setUseFillColor(useFC); } + + UMLApp::app()->endMacro(); } /** @@ -1327,9 +1311,13 @@ */ void UMLScene::selectionSetFont(const QFont &font) { + UMLApp::app()->beginMacro(i18n("Change font")); + foreach(UMLWidget* temp, selectedWidgets()) { temp->setFont(font); } + + UMLApp::app()->endMacro(); } /** @@ -1337,16 +1325,16 @@ */ void UMLScene::selectionSetLineColor(const QColor &color) { - UMLApp::app()->beginMacro(i18n("Change Line Color")); + UMLApp::app()->beginMacro(i18n("Change line color")); + foreach(UMLWidget *temp, selectedWidgets()) { temp->setLineColor(color); - temp->setUsesDiagramLineColor(false); } AssociationWidgetList assoclist = selectedAssocs(); foreach(AssociationWidget *aw, assoclist) { aw->setLineColor(color); - aw->setUsesDiagramLineColor(false); } + UMLApp::app()->endMacro(); } @@ -1355,6 +1343,8 @@ */ void UMLScene::selectionSetLineWidth(uint width) { + UMLApp::app()->beginMacro(i18n("Change line width")); + foreach(UMLWidget* temp, selectedWidgets()) { temp->setLineWidth(width); temp->setUsesDiagramLineWidth(false); @@ -1364,6 +1354,8 @@ aw->setLineWidth(width); aw->setUsesDiagramLineWidth(false); } + + UMLApp::app()->endMacro(); } /** @@ -1371,69 +1363,29 @@ */ void UMLScene::selectionSetFillColor(const QColor &color) { - UMLApp::app()->beginMacro(i18n("Change Fill Color")); + UMLApp::app()->beginMacro(i18n("Change fill color")); foreach(UMLWidget* widget, selectedWidgets()) { widget->setFillColor(color); widget->setUsesDiagramFillColor(false); } + UMLApp::app()->endMacro(); } /** - * Toggles the show setting sel of all selected items. + * Set or unset the visual property (show ..) setting of all selected items. */ -void UMLScene::selectionToggleShow(int sel) +void UMLScene::selectionSetVisualProperty(ClassifierWidget::VisualProperty property, bool value) { - // loop through all selected items + UMLApp::app()->beginMacro(i18n("Change visual property")); + foreach(UMLWidget *temp, selectedWidgets()) { - WidgetBase::WidgetType type = temp->baseType(); ClassifierWidget *cw = dynamic_cast(temp); - - // toggle the show setting sel - switch (sel) { - // some setting are only available for class, some for interface and some - // for both - case ListPopupMenu::mt_Show_Attributes_Selection: - if (type == WidgetBase::wt_Class) - cw->toggleVisualProperty(ClassifierWidget::ShowAttributes); - break; - case ListPopupMenu::mt_Show_Operations_Selection: - if (cw) - cw->toggleVisualProperty(ClassifierWidget::ShowOperations); - break; - case ListPopupMenu::mt_Visibility_Selection: - if (cw) - cw->toggleVisualProperty(ClassifierWidget::ShowVisibility); - break; - case ListPopupMenu::mt_DrawAsCircle_Selection: - if (type == WidgetBase::wt_Interface) - cw->toggleVisualProperty(ClassifierWidget::DrawAsCircle); - break; - case ListPopupMenu::mt_Show_Operation_Signature_Selection: - if (cw) - cw->toggleVisualProperty(ClassifierWidget::ShowOperationSignature); - break; - case ListPopupMenu::mt_Show_Attribute_Signature_Selection: - if (type == WidgetBase::wt_Class) - cw->toggleVisualProperty(ClassifierWidget::ShowAttributeSignature); - break; - case ListPopupMenu::mt_Show_Packages_Selection: - if (cw) - cw->toggleVisualProperty(ClassifierWidget::ShowPackage); - break; - case ListPopupMenu::mt_Show_Stereotypes_Selection: - if (type == WidgetBase::wt_Class) - cw->toggleVisualProperty(ClassifierWidget::ShowStereotype); - break; - case ListPopupMenu::mt_Show_Public_Only_Selection: - if (cw) - cw->toggleVisualProperty(ClassifierWidget::ShowPublicOnly); - break; - default: - break; - } // switch (sel) + cw->setVisualProperty(property, value); } + + UMLApp::app()->endMacro(); } /** @@ -1441,13 +1393,20 @@ */ void UMLScene::deleteSelection() { - // Don't delete text widget that are connect to associations as these will - // be cleaned up by the associations. + int selectionCount = (selectedWidgets().count() + + m_AssociationList.count() + + m_MessageList.count()); + + if (selectionCount > 1) { + UMLApp::app()->beginMacro(i18n("Delete widgets")); + } foreach(UMLWidget* widget, selectedWidgets()) { + // Don't delete text widget that are connect to associations as these will + // be cleaned up by the associations. if (widget->baseType() == WidgetBase::wt_Text && static_cast(widget)->textRole() != Uml::TextRole::Floating) { - m_selectedList.removeAt(m_selectedList.indexOf(widget)); + widget->setSelectedFlag(false); widget->hide(); } else { removeWidget(widget); @@ -1471,11 +1430,15 @@ } // sometimes we miss one widget, so call this function again to remove it as well - if (m_selectedList.count() != 0) - deleteSelection(); + //if (selectedWidgets().count() != 0) + // deleteSelection(); //make sure list empty - it should be anyway, just a check. - m_selectedList.clear(); + clearSelected(); + + if (selectionCount > 1) { + UMLApp::app()->endMacro(); + } } /** @@ -1483,12 +1446,22 @@ */ void UMLScene::resizeSelection() { + int selectionCount = selectedWidgets().count(); + + if (selectionCount > 1) { + UMLApp::app()->beginMacro(i18n("Resize widgets")); + } + if (selectedCount() == 0) return; foreach(UMLWidget *w, selectedWidgets()) { w->resize(); } m_doc->setModified(); + + if (selectionCount > 1) { + UMLApp::app()->endMacro(); + } } /** @@ -1500,17 +1473,6 @@ } /** - * Return a unique ID for the diagram. Used by the @ref ObjectWidget class. - * - * @return Return a unique ID for the diagram. - */ -Uml::ID::Type UMLScene::localID() -{ - m_nLocalID = UniqueID::gen(); - return m_nLocalID; -} - -/** * Returns true if this diagram resides in an externalized folder. * CHECK: It is probably cleaner to move this to the UMLListViewItem. */ @@ -1565,8 +1527,6 @@ { if (uw) { uw->setSelected(true); - m_selectedList.removeAll(uw); // make sure not in there - m_selectedList.append(uw); } } @@ -1613,51 +1573,75 @@ rect.setBottom(py); } + // Select UMLWidgets that fall within the selection rectangle foreach(UMLWidget* temp, m_WidgetList) { - int x = temp->x(); - int y = temp->y(); - int w = temp->width(); - int h = temp->height(); - QRectF rect2(x, y, w, h); + selectWidget(temp, &rect); + } - //see if any part of widget is in the rectangle - if (!rect.intersects(rect2)) - continue; - //if it is text that is part of an association then select the association - //and the objects that are connected to it. - if (temp->baseType() == WidgetBase::wt_Text) { - FloatingTextWidget *ft = static_cast(temp); - Uml::TextRole::Enum t = ft->textRole(); - LinkWidget *lw = ft->link(); - MessageWidget * mw = dynamic_cast(lw); - if (mw) { - makeSelected(mw); - makeSelected(mw->objectWidget(Uml::RoleType::A)); - makeSelected(mw->objectWidget(Uml::RoleType::B)); - } else if (t != Uml::TextRole::Floating) { - AssociationWidget * a = dynamic_cast(lw); - if (a) - selectWidgetsOfAssoc(a); - } - } else if (temp->baseType() == WidgetBase::wt_Message) { - MessageWidget *mw = static_cast(temp); - makeSelected(mw->objectWidget(Uml::RoleType::A)); - makeSelected(mw->objectWidget(Uml::RoleType::B)); - } - if (temp->isVisible()) { - makeSelected(temp); - } + // Select messages that fall within the selection rectangle + foreach(MessageWidget* temp, m_MessageList) { + selectWidget(dynamic_cast(temp), &rect); } - selectAssociations(true); - //now do the same for the messagewidgets + // Select associations of selected widgets + selectAssociations(true); + // Automatically select all messages if two object widgets are selected foreach(MessageWidget *w, m_MessageList) { if (w->objectWidget(Uml::RoleType::A)->isSelected() && w->objectWidget(Uml::RoleType::B)->isSelected()) { makeSelected(w); - }//end if - }//end foreach + } + } +} + +/** + * Select a single widget + * + * If QRectF* rect is provided, the selection is only made if the widget is + * visible within the rectangle. + */ +void UMLScene::selectWidget(UMLWidget* widget, QRectF* rect) +{ + if (rect == 0) { + makeSelected(widget); + return; + } + + int x = widget->x(); + int y = widget->y(); + int w = widget->width(); + int h = widget->height(); + QRectF rect2(x, y, w, h); + + //see if any part of widget is in the rectangle + if (!rect->intersects(rect2)) { + return; + } + + //if it is text that is part of an association then select the association + //and the objects that are connected to it. + if (widget->baseType() == WidgetBase::wt_Text) { + FloatingTextWidget *ft = static_cast(widget); + Uml::TextRole::Enum t = ft->textRole(); + LinkWidget *lw = ft->link(); + MessageWidget * mw = dynamic_cast(lw); + if (mw) { + makeSelected(mw); + makeSelected(mw->objectWidget(Uml::RoleType::A)); + makeSelected(mw->objectWidget(Uml::RoleType::B)); + } else if (t != Uml::TextRole::Floating) { + AssociationWidget * a = dynamic_cast(lw); + if (a) + selectWidgetsOfAssoc(a); + } + } else if (widget->baseType() == WidgetBase::wt_Message) { + MessageWidget *mw = static_cast(widget); + makeSelected(mw); + } + if (widget->isVisible()) { + makeSelected(widget); + } } /** @@ -1884,33 +1868,10 @@ } /** - * Adds a widget to the view from the given data. - * Use this method when pasting. + * Adds a floating text widget to the view */ -bool UMLScene::addWidget(UMLWidget * pWidget, bool isPasteOperation) +void UMLScene::addFloatingTextWidget(FloatingTextWidget* pWidget) { - if (!pWidget) { - return false; - } - WidgetBase::WidgetType type = pWidget->baseType(); - if (isPasteOperation) { - if (type == WidgetBase::wt_Message) - m_MessageList.append(static_cast(pWidget)); - else - m_WidgetList.append(pWidget); - return true; - } - if (!isPasteOperation && findWidget(pWidget->id())) { - uError() << "Not adding (id=" << Uml::ID::toString(pWidget->id()) - << "/type=" << pWidget->baseTypeStr() << "/name=" << pWidget->name() - << ") because it is already there"; - return false; - } - IDChangeLog * log = m_doc->changeLog(); - if (isPasteOperation && (!log || !m_pIDChangesLog)) { - uError() << " Cannot addWidget to view in paste op because a log is not open"; - return false; - } int wX = pWidget->x(); int wY = pWidget->y(); bool xIsOutOfRange = (wX < sceneRect().left() || wX > sceneRect().right()); @@ -1933,183 +1894,8 @@ wY = 0; } } - if (wX < m_Pos.x()) - m_Pos.setX(wX); - if (wY < m_Pos.y()) - m_Pos.setY(wY); - - //see if we need a new id to match object - switch (type) { - - case WidgetBase::wt_Class: - case WidgetBase::wt_Package: - case WidgetBase::wt_Component: - case WidgetBase::wt_Node: - case WidgetBase::wt_Artifact: - case WidgetBase::wt_Interface: - case WidgetBase::wt_Enum: - case WidgetBase::wt_Entity: - case WidgetBase::wt_Datatype: - case WidgetBase::wt_Actor: - case WidgetBase::wt_UseCase: - case WidgetBase::wt_Category: { - Uml::ID::Type id = pWidget->id(); - Uml::ID::Type newID = log ? log->findNewID(id) : Uml::ID::None; - if (newID == Uml::ID::None) { // happens after a cut - if (id == Uml::ID::None) - return false; - newID = id; //don't stop paste - } else - pWidget->setID(newID); - UMLObject * pObject = m_doc->findObjectById(newID); - if (!pObject) { - DEBUG(DBG_SRC) << "addWidget: Can not find UMLObject for id " - << Uml::ID::toString(newID); - return false; - } - pWidget->setUMLObject(pObject); - //make sure it doesn't already exist. - if (findWidget(newID)) { - DEBUG(DBG_SRC) << "Not adding (id=" << Uml::ID::toString(pWidget->id()) - << "/type=" << pWidget->baseTypeStr() - << "/name=" << pWidget->name() - << ") because it is already there"; - delete pWidget; // Not nice but if _we_ don't do it nobody else will - return true;//don't stop paste just because widget found. - } - m_WidgetList.append(pWidget); - } - break; - - case WidgetBase::wt_Message: - case WidgetBase::wt_Note: - case WidgetBase::wt_Box: - case WidgetBase::wt_Text: - case WidgetBase::wt_State: - case WidgetBase::wt_Activity: - case WidgetBase::wt_ObjectNode: { - Uml::ID::Type newID = m_doc->assignNewID(pWidget->id()); - pWidget->setID(newID); - if (type != WidgetBase::wt_Message) { - m_WidgetList.append(pWidget); - return true; - } - // CHECK - // Handling of WidgetBase::wt_Message: - MessageWidget *pMessage = static_cast(pWidget); - if (pMessage == NULL) { - DEBUG(DBG_SRC) << "pMessage is NULL"; - return false; - } - ObjectWidget *objWidgetA = pMessage->objectWidget(Uml::RoleType::A); - ObjectWidget *objWidgetB = pMessage->objectWidget(Uml::RoleType::B); - Uml::ID::Type waID = objWidgetA->localID(); - Uml::ID::Type wbID = objWidgetB->localID(); - Uml::ID::Type newWAID = m_pIDChangesLog->findNewID(waID); - Uml::ID::Type newWBID = m_pIDChangesLog->findNewID(wbID); - if (newWAID == Uml::ID::None || newWBID == Uml::ID::None) { - DEBUG(DBG_SRC) << "Error with ids : " << Uml::ID::toString(newWAID) - << " " << Uml::ID::toString(newWBID); - return false; - } - // Assumption here is that the A/B objectwidgets and the textwidget - // are pristine in the sense that we may freely change their local IDs. - objWidgetA->setLocalID(newWAID); - objWidgetB->setLocalID(newWBID); - FloatingTextWidget *ft = pMessage->floatingTextWidget(); - if (ft == NULL) { - DEBUG(DBG_SRC) << "FloatingTextWidget of Message is NULL"; - } - else if (ft->id() == Uml::ID::None) { - ft->setID(UniqueID::gen()); - } - else { - Uml::ID::Type newTextID = m_doc->assignNewID(ft->id()); - ft->setID(newTextID); - } - m_MessageList.append(pMessage); - } - break; - case WidgetBase::wt_Object: { - ObjectWidget* pObjectWidget = static_cast(pWidget); - if (pObjectWidget == NULL) { - DEBUG(DBG_SRC) << "pObjectWidget is NULL"; - return false; - } - Uml::ID::Type nNewLocalID = localID(); - Uml::ID::Type nOldLocalID = pObjectWidget->localID(); - m_pIDChangesLog->addIDChange(nOldLocalID, nNewLocalID); - pObjectWidget->setLocalID(nNewLocalID); - UMLObject *pObject = m_doc->findObjectById(pWidget->id()); - if (!pObject) { - DEBUG(DBG_SRC) << "Cannot find UMLObject"; - return false; - } - pWidget->setUMLObject(pObject); - m_WidgetList.append(pWidget); - } - break; - - case WidgetBase::wt_Precondition: { - ObjectWidget* pObjectWidget = static_cast(pWidget); - if (pObjectWidget == NULL) { - DEBUG(DBG_SRC) << "pObjectWidget is NULL"; - return false; - } - Uml::ID::Type newID = log->findNewID(pWidget->id()); - if (newID == Uml::ID::None) { - return false; - } - pObjectWidget->setID(newID); - Uml::ID::Type nNewLocalID = localID(); - Uml::ID::Type nOldLocalID = pObjectWidget->localID(); - m_pIDChangesLog->addIDChange(nOldLocalID, nNewLocalID); - pObjectWidget->setLocalID(nNewLocalID); - UMLObject *pObject = m_doc->findObjectById(newID); - if (!pObject) { - DEBUG(DBG_SRC) << "Cannot find UMLObject"; - return false; - } - pWidget->setUMLObject(pObject); - m_WidgetList.append(pWidget); - } - break; - - case WidgetBase::wt_Pin: - case WidgetBase::wt_CombinedFragment: - case WidgetBase::wt_Signal: { - ObjectWidget* pObjectWidget = static_cast(pWidget); - if (pObjectWidget == NULL) { - DEBUG(DBG_SRC) << "pObjectWidget is NULL"; - return false; - } - Uml::ID::Type newID = log->findNewID(pWidget->id()); - if (newID == Uml::ID::None) { - return false; - } - pObjectWidget->setID(newID); - Uml::ID::Type nNewLocalID = localID(); - Uml::ID::Type nOldLocalID = pObjectWidget->localID(); - m_pIDChangesLog->addIDChange(nOldLocalID, nNewLocalID); - pObjectWidget->setLocalID(nNewLocalID); - UMLObject *pObject = m_doc->findObjectById(newID); - if (!pObject) { - DEBUG(DBG_SRC) << "Cannot find UMLObject"; - return false; - } - pWidget->setUMLObject(pObject); - m_WidgetList.append(pWidget); - } - break; - - default: - DEBUG(DBG_SRC) << "Trying to add an invalid widget type"; - return false; - break; - } - - return true; + m_WidgetList.append(pWidget); } /** @@ -2197,7 +1983,7 @@ FloatingTextWidget *flotxt = ft[i]; if (flotxt) { flotxt->updateGeometry(); - addWidget(flotxt); + addFloatingTextWidget(flotxt); } } @@ -2370,7 +2156,7 @@ // crashes on exit. Still to be analyzed. --okellogg if (!(temp->baseType() == WidgetBase::wt_Text && ((FloatingTextWidget *)temp)->textRole() != TextRole::Floating)) { - removeWidget(temp); + removeWidgetCmd(temp); } } @@ -2501,7 +2287,7 @@ } else if (roleBObj->id() == myID) { other = static_cast(roleAObj); } else { - DEBUG(DBG_SRC) << "Can not find own object " + DEBUG(DBG_SRC) << "Cannot find own object " << Uml::ID::toString(myID) << " in UMLAssoc " << Uml::ID::toString(assoc->id()); continue; @@ -2887,7 +2673,7 @@ qreal px = -1, py = -1, qx = -1, qy = -1; //first get the smallest rect holding the widgets - foreach(UMLWidget* temp, m_selectedList) { + foreach(UMLWidget* temp, selectedWidgets()) { qreal x = temp->x(); qreal y = temp->y(); qreal x1 = x + temp->width() - 1; @@ -2956,12 +2742,8 @@ */ void UMLScene::contextMenuEvent(QGraphicsSceneContextMenuEvent* contextMenuEvent) { - if (onItem(contextMenuEvent->scenePos())) { - // forward the event to the item - QGraphicsScene::contextMenuEvent(contextMenuEvent); - } - else { - // set the position for the eventually created widget + QGraphicsScene::contextMenuEvent(contextMenuEvent); + if (!contextMenuEvent->isAccepted()) { setPos(contextMenuEvent->scenePos()); setMenu(contextMenuEvent->screenPos()); contextMenuEvent->accept(); @@ -3435,11 +3217,9 @@ pWB = pMessage->objectWidget(Uml::RoleType::B); if (!pWA->isSelected()) { pWA->setSelectedFlag(true); - m_selectedList.append(pWA); } if (!pWB->isSelected()) { pWB->setSelectedFlag(true); - m_selectedList.append(pWB); } }//end if }//end for @@ -3451,40 +3231,38 @@ pWB = pAssoc->widgetForRole(Uml::RoleType::B); if (!pWA->isSelected()) { pWA->setSelectedFlag(true); - m_selectedList.append(pWA); } if (!pWB->isSelected()) { pWB->setSelectedFlag(true); - m_selectedList.append(pWB); } }//end if }//end foreach } /** - * This function checks if the currently selected items have all the same - * type (class, interface, ...). If true, the selection is unique and true - * will be returned. - * If there are no items selected, the function will return always true. - */ -bool UMLScene::checkUniqueSelection() -{ - // if there are no selected items, we return true - if (selectedWidgets().isEmpty()) - return true; + * Returns the type of the selected widget or widgets. + * + * If multiple widgets of different types are selected. WidgetType::UMLWidget + * is returned. + */ +WidgetBase::WidgetType UMLScene::getUniqueSelectionType() +{ + if (selectedWidgets().isEmpty()) { + return WidgetBase::wt_UMLWidget; + } - // get the first item and its base type + // Get the first item and its base type UMLWidget * pTemp = (UMLWidget *) selectedWidgets().first(); WidgetBase::WidgetType tmpType = pTemp->baseType(); - // check all selected items, if they have the same BaseType + // Check all selected items, if they have the same BaseType foreach(pTemp, selectedWidgets()) { if (pTemp->baseType() != tmpType) { - return false; // the base types are different, the list is not unique + return WidgetBase::wt_UMLWidget; } - } // for (through all selected items) + } - return true; // selected items are unique + return tmpType; } /** diff -Nru umbrello-4.12.3/umbrello/umlscene.h umbrello-4.12.90/umbrello/umlscene.h --- umbrello-4.12.3/umbrello/umlscene.h 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/umlscene.h 2014-03-05 15:04:09.000000000 +0000 @@ -14,12 +14,15 @@ // local includes #include "associationwidgetlist.h" #include "basictypes.h" +#include "classifierwidget.h" +#include "floatingtextwidget.h" #include "messagewidgetlist.h" #include "optionstate.h" #include "umlobject.h" #include "umlobjectlist.h" #include "umlwidgetlist.h" #include "worktoolbar.h" +#include "widgetbase.h" // Qt includes #include @@ -168,6 +171,7 @@ void checkMessages(ObjectWidget * w); UMLWidget* findWidget(Uml::ID::Type id); + UMLWidget* findWidgetByLocalId(Uml::ID::Type id); AssociationWidget* findAssocWidget(Uml::ID::Type id); AssociationWidget* findAssocWidget(Uml::AssociationType::Enum at, @@ -176,8 +180,8 @@ UMLWidget *pWidgetB, const QString& roleNameB); void removeWidget(UMLWidget *o); + void removeWidgetCmd(UMLWidget *o); - void setSelected(UMLWidget *w, QGraphicsSceneMouseEvent *me); UMLWidgetList selectedWidgets() const; void clearSelected(); @@ -190,15 +194,13 @@ void selectionSetLineColor(const QColor &color); void selectionSetLineWidth(uint width); void selectionSetFillColor(const QColor &color); - void selectionToggleShow(int sel); + void selectionSetVisualProperty(ClassifierWidget::VisualProperty property, bool value); void deleteSelection(); void resizeSelection(); void selectAll(); - Uml::ID::Type localID(); - bool widgetOnDiagram(Uml::ID::Type id); bool isSavedInSeparateFile(); @@ -241,7 +243,7 @@ void removeAssocInViewAndDoc(AssociationWidget* assoc); - bool addWidget(UMLWidget * pWidget, bool isPasteOperation = false); + void addFloatingTextWidget(FloatingTextWidget* pWidget); QPointF getPastePoint(); void resetPastePoint(); @@ -258,7 +260,7 @@ void checkSelections(); - bool checkUniqueSelection(); + WidgetBase::WidgetType getUniqueSelectionType(); void clearDiagram(); @@ -284,6 +286,7 @@ void selectWidgets(qreal px, qreal py, qreal qx, qreal qy); void selectWidgets(UMLWidgetList &widgets); + void selectWidget(UMLWidget* widget, QRectF* rect = 0); void selectWidgetsOfAssoc(AssociationWidget *a); ObjectWidget * onWidgetLine(const QPointF &point) const; @@ -363,7 +366,6 @@ bool m_bDrawSelectedOnly; bool m_bPaste; bool m_bStartedCut; ///< Flag if view/children started cut operation. - UMLWidgetList m_selectedList; ///< list of selected items TODO: migrate to QGraphicsScenes selection list private: static const qreal defaultCanvasSize; ///< The default size of a diagram in pixels. @@ -391,8 +393,6 @@ UMLForeignKeyConstraint* fkConstraint, UMLWidget* widget); - bool onItem(const QPointF& atPos); - public slots: void slotToolBarChanged(int c); void slotObjectCreated(UMLObject * o); diff -Nru umbrello-4.12.3/umbrello/umlviewimageexportermodel.cpp umbrello-4.12.90/umbrello/umlviewimageexportermodel.cpp --- umbrello-4.12.3/umbrello/umlviewimageexportermodel.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/umlviewimageexportermodel.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -226,7 +226,7 @@ // create the needed directories if (!prepareDirectory(url)) { - return i18n("Can not create directory: %1", url.directory()); + return i18n("Cannot create directory: %1", url.directory()); } // The fileName will be used when exporting the image. If the url isn't local, @@ -243,7 +243,7 @@ QRectF rect = scene->diagramRect(); if (rect.isEmpty()) { - return i18n("Can not save an empty diagram"); + return i18n("Cannot save an empty diagram"); } // exporting the view to the file diff -Nru umbrello-4.12.3/umbrello/version.h umbrello-4.12.90/umbrello/version.h --- umbrello-4.12.3/umbrello/version.h 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/version.h 2014-03-05 15:04:09.000000000 +0000 @@ -27,6 +27,6 @@ } // Update this version when changing the XMI file format -#define XMI_FILE_VERSION "1.6.2" +#define XMI_FILE_VERSION "1.6.3" #endif diff -Nru umbrello-4.12.3/umbrello/widgets/artifactwidget.cpp umbrello-4.12.90/umbrello/widgets/artifactwidget.cpp --- umbrello-4.12.3/umbrello/widgets/artifactwidget.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/widgets/artifactwidget.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -57,16 +57,16 @@ UMLArtifact::Draw_Type drawType = umlart->getDrawAsType(); switch (drawType) { case UMLArtifact::defaultDraw: - paintAsNormal(painter); + paintAsNormal(painter, option); break; case UMLArtifact::file: - paintAsFile(painter); + paintAsFile(painter, option); break; case UMLArtifact::library: - paintAsLibrary(painter); + paintAsLibrary(painter, option); break; case UMLArtifact::table: - paintAsTable(painter); + paintAsTable(painter, option); break; default: uWarning() << "Artifact drawn as unknown type"; @@ -147,7 +147,7 @@ /** * draw as a file icon */ -void ArtifactWidget::paintAsFile(QPainter *painter) +void ArtifactWidget::paintAsFile(QPainter *painter, const QStyleOptionGraphicsItem *option) { const int w = width(); const int h = height(); @@ -175,13 +175,13 @@ painter->drawText(0, h - fontHeight, w, fontHeight, Qt::AlignCenter, name()); - UMLWidget::paint(painter, 0); + UMLWidget::paint(painter, option); } /** * draw as a library file icon */ -void ArtifactWidget::paintAsLibrary(QPainter *painter) +void ArtifactWidget::paintAsLibrary(QPainter *painter, const QStyleOptionGraphicsItem *option) { //FIXME this should have gears on it const int w = width(); @@ -210,13 +210,13 @@ painter->drawText(0, h - fontHeight, w, fontHeight, Qt::AlignCenter, name()); - UMLWidget::paint(painter, 0); + UMLWidget::paint(painter, option); } /** * draw as a database table icon */ -void ArtifactWidget::paintAsTable(QPainter *painter) +void ArtifactWidget::paintAsTable(QPainter *painter, const QStyleOptionGraphicsItem *option) { const int w = width(); const int h = height(); @@ -247,13 +247,13 @@ painter->drawText(0, h - fontHeight, w, fontHeight, Qt::AlignCenter, name()); - UMLWidget::paint(painter, 0); + UMLWidget::paint(painter, option); } /** * draw as a box */ -void ArtifactWidget::paintAsNormal(QPainter *painter) +void ArtifactWidget::paintAsNormal(QPainter *painter, const QStyleOptionGraphicsItem *option) { int w = width(); int h = height(); @@ -288,6 +288,6 @@ w, fontHeight, Qt::AlignCenter, name()); } - UMLWidget::paint(painter, 0); + UMLWidget::paint(painter, option); } diff -Nru umbrello-4.12.3/umbrello/widgets/artifactwidget.h umbrello-4.12.90/umbrello/widgets/artifactwidget.h --- umbrello-4.12.3/umbrello/widgets/artifactwidget.h 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/widgets/artifactwidget.h 2014-03-05 15:04:09.000000000 +0000 @@ -42,10 +42,10 @@ QSizeF minimumSize(); private: - void paintAsFile(QPainter *painter); - void paintAsLibrary(QPainter *painter); - void paintAsTable(QPainter *painter); - void paintAsNormal(QPainter *painter); + void paintAsFile(QPainter *painter, const QStyleOptionGraphicsItem *option); + void paintAsLibrary(QPainter *painter, const QStyleOptionGraphicsItem *option); + void paintAsTable(QPainter *painter, const QStyleOptionGraphicsItem *option); + void paintAsNormal(QPainter *painter, const QStyleOptionGraphicsItem *option); QSize calculateIconSize(); QSize calculateNormalSize(); diff -Nru umbrello-4.12.3/umbrello/widgets/associationline.cpp umbrello-4.12.90/umbrello/widgets/associationline.cpp --- umbrello-4.12.3/umbrello/widgets/associationline.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/widgets/associationline.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -970,7 +970,6 @@ painter->drawLine(segmentLine); } } - // debug info if (Tracer::instance()->isEnabled(metaObject()->className())) { painter->setPen(Qt::green); @@ -982,6 +981,7 @@ painter->drawLine(-10, 0, 10, 0); painter->drawLine(0, -10, 0, 10); } + } // now restore the points array diff -Nru umbrello-4.12.3/umbrello/widgets/associationwidget.cpp umbrello-4.12.90/umbrello/widgets/associationwidget.cpp --- umbrello-4.12.3/umbrello/widgets/associationwidget.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/widgets/associationwidget.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -64,7 +64,6 @@ m_positions_len(0), m_activated(false), m_unNameLineSegment(-1), - m_selected(false), m_nLinePathSegmentIndex(-1), m_pAssocClassLine(0), m_pAssocClassLineSel0(0), @@ -618,7 +617,7 @@ m_unNameLineSegment = other.m_unNameLineSegment; m_pMenu = other.m_pMenu; setUMLAssociation(other.association()); - m_selected = other.m_selected; + setSelected(other.isSelected()); return *this; } @@ -729,7 +728,7 @@ setWidgetForRole(m_scene->findWidget(widgetIDForRole(RoleType::B)), RoleType::B); if(!m_role[RoleType::A].umlWidget || !m_role[RoleType::B].umlWidget) { - DEBUG(DBG_SRC) << "Can not make association!"; + DEBUG(DBG_SRC) << "Cannot make association!"; return false; } @@ -939,7 +938,7 @@ setTextPosition(Uml::TextRole::Name); if (newLabel) { m_nameWidget->setActivated(); - m_scene->addWidget(m_nameWidget); + m_scene->addFloatingTextWidget(m_nameWidget); } m_nameWidget->show(); @@ -1043,7 +1042,7 @@ ft->setLink(this); ft->activate(); setTextPosition(role); - m_scene->addWidget(ft); + m_scene->addFloatingTextWidget(ft); } else { bool newLabel = ft->text().isEmpty(); ft->setText(text); @@ -1162,7 +1161,7 @@ m_role[role].changeabilityWidget = new FloatingTextWidget(m_scene, tr, strChangeWidget); m_role[role].changeabilityWidget->setParentItem(this); m_role[role].changeabilityWidget->setLink(this); - m_scene->addWidget(m_role[role].changeabilityWidget); + m_scene->addFloatingTextWidget(m_role[role].changeabilityWidget); m_role[role].changeabilityWidget->setPreText("{"); // all types have this m_role[role].changeabilityWidget->setPostText("}"); // all types have this } else { @@ -1332,7 +1331,7 @@ */ bool AssociationWidget::isPointAddable() { - if (!m_selected || associationType() == Uml::AssociationType::Exception) + if (!isSelected() || associationType() == Uml::AssociationType::Exception) return false; int i = m_associationLine->closestPointIndex(m_eventScenePos); return i == -1; @@ -1347,7 +1346,7 @@ */ bool AssociationWidget::isPointRemovable() { - if (!m_selected || associationType() == Uml::AssociationType::Exception || m_associationLine->count() <= 2) + if (!isSelected() || associationType() == Uml::AssociationType::Exception || m_associationLine->count() <= 2) return false; int i = m_associationLine->closestPointIndex(m_eventScenePos); return i > 0 && i < m_associationLine->count() - 1; @@ -1489,6 +1488,25 @@ } /** + * Gets the local ID of the given role widget. + */ +Uml::ID::Type AssociationWidget::widgetLocalIDForRole(Uml::RoleType::Enum role) const +{ + if (m_role[role].umlWidget == NULL) { + if (m_umlObject && m_umlObject->baseType() == UMLObject::ot_Association) { + UMLAssociation *umla = static_cast(m_umlObject); + return umla->getObjectId(role); + } + uError() << "umlWidget is NULL"; + return Uml::ID::None; + } + if (m_role[role].umlWidget->baseType() == WidgetBase::wt_Object) + return static_cast(m_role[role].umlWidget)->localID(); + Uml::ID::Type id = m_role[role].umlWidget->localID(); + return id; +} + +/** * Returns a QString Object representing this AssociationWidget. */ QString AssociationWidget::toString() const @@ -2462,7 +2480,7 @@ p = m_associationLine->point(0); q = m_associationLine->point(1); } else if (role == TextRole::MultiB || role == TextRole::ChangeB || role == TextRole::RoleBName) { - const uint lastSegment = m_associationLine->count() - 1; + const int lastSegment = m_associationLine->count() - 1; p = m_associationLine->point(lastSegment); q = m_associationLine->point(lastSegment - 1); } else if (role != TextRole::Name) { @@ -2565,7 +2583,7 @@ { const int textCenterX = textX + textWidth / 2; const int textCenterY = textY + textHeight / 2; - const uint lastSegment = m_associationLine->count() - 1; + const int lastSegment = m_associationLine->count() - 1; QPointF p0, p1; switch (tr) { case TextRole::RoleAName: @@ -2596,7 +2614,7 @@ { int minDistSquare = 100000; // utopian initial value int lpIndex = 0; - for (uint i = 0; i < lastSegment; ++i) { + for (int i = 0; i < lastSegment; ++i) { p0 = m_associationLine->point(i); p1 = m_associationLine->point(i + 1); QPointF midP = midPoint(p0, p1); @@ -2632,7 +2650,7 @@ const int y0 = p0.y(); const int x1 = p1.x(); const int y1 = p1.y(); - double r = sqrt((x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0)) / 2; + double r = sqrt((double)((x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0))) / 2; if (textWidth > r) r = textWidth; // swap textCenter{X,Y} to convert from Qt coord.system. @@ -2909,11 +2927,11 @@ QPointF mep = me->scenePos(); // see if `mep' is on the connecting line to the association class if (onAssocClassLine(mep)) { - m_selected = true; + setSelected(true); selectAssocClassLine(); return; } - setSelected( !m_selected ); + setSelected(!isSelected()); associationLine()->mousePressEvent(me); } @@ -3041,16 +3059,6 @@ } break; - case ListPopupMenu::mt_Change_Font_Selection: - { - QFont fnt = font(); - if (KFontDialog::getFont( fnt, KFontChooser::NoDisplayFlags, m_scene->activeView())) { - m_scene->selectionSetFont( fnt ); - umlDoc()->setModified(true); - } - } - break; - case ListPopupMenu::mt_Line_Color: { QColor newColor; @@ -3239,7 +3247,7 @@ return; } - setSelected(); + setSelected(true); // new position for point QPointF p = me->scenePos(); @@ -3658,23 +3666,13 @@ } /** - * Returns the state of whether the widget is selected. - * - * @return Returns the state of whether the widget is selected. - */ -bool AssociationWidget::isSelected() const -{ - return m_selected; -} - -/** * Sets the state of whether the widget is selected. * * @param _select The state of whether the widget is selected. */ void AssociationWidget::setSelected(bool _select /* = true */) { - m_selected = _select; + WidgetBase::setSelected(_select); if ( m_nameWidget) m_nameWidget->setSelected( _select ); if ( m_role[RoleType::A].roleWidget ) diff -Nru umbrello-4.12.3/umbrello/widgets/associationwidget.h umbrello-4.12.90/umbrello/widgets/associationwidget.h --- umbrello-4.12.3/umbrello/widgets/associationwidget.h 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/widgets/associationwidget.h 2014-03-05 15:04:09.000000000 +0000 @@ -122,6 +122,7 @@ void setChangeability(Uml::Changeability::Enum value, Uml::RoleType::Enum role); Uml::ID::Type widgetIDForRole(Uml::RoleType::Enum role) const; + Uml::ID::Type widgetLocalIDForRole(Uml::RoleType::Enum role) const; UMLWidget* widgetForRole(Uml::RoleType::Enum role) const; void setWidgetForRole(UMLWidget* widget, Uml::RoleType::Enum role); @@ -140,9 +141,6 @@ bool isActivated() const; void setActivated(bool active); - bool isSelected() const; - void setSelected(bool _select = true); - AssociationLine* associationLine() const; virtual bool activate(); @@ -194,6 +192,7 @@ virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + virtual void setSelected(bool _select); public Q_SLOTS: //:TODO: all virtual? virtual void slotMenuSelection(QAction* action); void slotClearAllSelected(); @@ -301,7 +300,6 @@ * m_associationLine[m_unNameLineSegment] -- m_associationLine[m_unNameLineSegment+1] */ int m_unNameLineSegment; - bool m_selected; QPointF m_oldNamePoint; ///< Position of name floatingtext saved by saveIdealTextPositions() QPointF m_oldMultiAPoint; ///< Position of role A multiplicity floatingtext saved by saveIdealTextPositions() diff -Nru umbrello-4.12.3/umbrello/widgets/classifierwidget.cpp umbrello-4.12.90/umbrello/widgets/classifierwidget.cpp --- umbrello-4.12.3/umbrello/widgets/classifierwidget.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/widgets/classifierwidget.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -14,6 +14,7 @@ // app includes #include "associationwidget.h" #include "classifier.h" +#include "cmds.h" #include "debug_utils.h" #include "listpopupmenu.h" #include "object_factory.h" @@ -42,10 +43,10 @@ m_pAssocWidget(0) { const Settings::OptionState& ops = m_scene->optionState(); - setVisualProperty(ShowVisibility, ops.classState.showVisibility); - setVisualProperty(ShowOperations, ops.classState.showOps); - setVisualProperty(ShowPublicOnly, ops.classState.showPublicOnly); - setVisualProperty(ShowPackage, ops.classState.showPackage); + setVisualPropertyCmd(ShowVisibility, ops.classState.showVisibility); + setVisualPropertyCmd(ShowOperations, ops.classState.showOps); + setVisualPropertyCmd(ShowPublicOnly, ops.classState.showPublicOnly); + setVisualPropertyCmd(ShowPackage, ops.classState.showPackage); m_attributeSignature = Uml::SignatureType::ShowSig; /*:TODO: setVisualProperty(ShowOperationSignature, ops.classState.showOpSig); @@ -62,9 +63,9 @@ else m_operationSignature = Uml::SignatureType::SigNoVis; - setVisualProperty(ShowAttributes, ops.classState.showAtts); - setVisualProperty(ShowStereotype, ops.classState.showStereoType); - setVisualProperty(DrawAsCircle, false); + setVisualPropertyCmd(ShowAttributes, ops.classState.showAtts); + setVisualPropertyCmd(ShowStereotype, ops.classState.showStereoType); + setVisualPropertyCmd(DrawAsCircle, false); setShowAttSigs(ops.classState.showAttSig); @@ -142,6 +143,8 @@ /** * A convenient method to set and reset individual VisualProperty * + * Undo command. + * * @param property The property to be set/reset. * @param enable True/false to set/reset. (default = true) * @@ -150,6 +153,22 @@ */ void ClassifierWidget::setVisualProperty(VisualProperty property, bool enable) { + if (visualProperty(property) != enable) { + UMLApp::app()->executeCommand(new Uml::CmdChangeVisualProperty(this, property, enable)); + } +} + +/** + * A convenient method to set and reset individual VisualProperty + * + * @param property The property to be set/reset. + * @param enable True/false to set/reset. (default = true) + * + * @note This method handles ShowAttributeSignature and + * ShowOperationSignature specially. + */ +void ClassifierWidget::setVisualPropertyCmd(VisualProperty property, bool enable) +{ // Handle ShowAttributeSignature and ShowOperationSignature // specially. @@ -185,7 +204,7 @@ m_visualProperties |= property; } else { - enable &= ~property; + m_visualProperties &= ~property; } setShowStereotype(enable); } @@ -567,7 +586,7 @@ painter->setBrush(m_scene->activeView()->viewport()->palette().color(QPalette::Background)); if (classifier()->isInterface() && visualProperty(DrawAsCircle)) { - drawAsCircle(painter); + drawAsCircle(painter, option); return; } @@ -682,10 +701,24 @@ } /** + * @return The shape of the ClassifierWidget. + */ +QPainterPath ClassifierWidget::shape() const +{ + if (classifier()->isInterface() && visualProperty(DrawAsCircle)) { + QPainterPath path; + path.addEllipse(width()/2 - CIRCLE_SIZE/2, 0, CIRCLE_SIZE, CIRCLE_SIZE); + path.addRect(0, CIRCLE_SIZE, width(), height() - CIRCLE_SIZE); + return path; + } + return UMLWidget::shape(); +} + +/** * Draws the interface as a circle with name underneath. * Only applies when m_umlObject->getBaseType() is ot_Interface. */ -void ClassifierWidget::drawAsCircle(QPainter *painter) +void ClassifierWidget::drawAsCircle(QPainter *painter, const QStyleOptionGraphicsItem *option) { int w = width(); @@ -705,7 +738,7 @@ painter->setFont(font); painter->drawText(0, CIRCLE_SIZE, w, fontHeight, Qt::AlignCenter, name); - UMLWidget::paint(painter, 0); + UMLWidget::paint(painter, option); } /** @@ -778,7 +811,7 @@ */ void ClassifierWidget::setDrawAsCircle(bool drawAsCircle) { - setVisualProperty(DrawAsCircle, drawAsCircle); + setVisualPropertyCmd(DrawAsCircle, drawAsCircle); updateGeometry(); update(); } @@ -884,12 +917,12 @@ QString showscope = qElement.attribute("showscope", "0"); QString drawascircle = qElement.attribute("drawascircle", "0"); - setVisualProperty(ShowAttributes, (bool)showatts.toInt()); - setVisualProperty(ShowOperations, (bool)showops.toInt()); - setVisualProperty(ShowPublicOnly, (bool)showpubliconly.toInt()); - setVisualProperty(ShowPackage, (bool)showpackage.toInt()); - setVisualProperty(ShowVisibility, (bool)showscope.toInt()); - setVisualProperty(DrawAsCircle, (bool)drawascircle.toInt()); + setVisualPropertyCmd(ShowAttributes, (bool)showatts.toInt()); + setVisualPropertyCmd(ShowOperations, (bool)showops.toInt()); + setVisualPropertyCmd(ShowPublicOnly, (bool)showpubliconly.toInt()); + setVisualPropertyCmd(ShowPackage, (bool)showpackage.toInt()); + setVisualPropertyCmd(ShowVisibility, (bool)showscope.toInt()); + setVisualPropertyCmd(DrawAsCircle, (bool)drawascircle.toInt()); m_attributeSignature = Uml::SignatureType::fromInt(showattsigs.toInt()); m_operationSignature = Uml::SignatureType::fromInt(showopsigs.toInt()); @@ -946,57 +979,46 @@ break; } case ListPopupMenu::mt_Show_Operations: - case ListPopupMenu::mt_Show_Operations_Selection: toggleVisualProperty(ShowOperations); break; case ListPopupMenu::mt_Show_Attributes: - case ListPopupMenu::mt_Show_Attributes_Selection: toggleVisualProperty(ShowAttributes); break; case ListPopupMenu::mt_Show_Public_Only: - case ListPopupMenu::mt_Show_Public_Only_Selection: toggleVisualProperty(ShowPublicOnly); break; case ListPopupMenu::mt_Show_Operation_Signature: - case ListPopupMenu::mt_Show_Operation_Signature_Selection: toggleVisualProperty(ShowOperationSignature); break; case ListPopupMenu::mt_Show_Attribute_Signature: - case ListPopupMenu::mt_Show_Attribute_Signature_Selection: toggleVisualProperty(ShowAttributeSignature); break; case ListPopupMenu::mt_Visibility: - case ListPopupMenu::mt_Visibility_Selection: toggleVisualProperty(ShowVisibility); break; case ListPopupMenu::mt_Show_Packages: - case ListPopupMenu::mt_Show_Packages_Selection: toggleVisualProperty(ShowPackage); break; case ListPopupMenu::mt_Show_Stereotypes: - case ListPopupMenu::mt_Show_Stereotypes_Selection: toggleVisualProperty(ShowStereotype); break; case ListPopupMenu::mt_DrawAsCircle: - case ListPopupMenu::mt_DrawAsCircle_Selection: toggleVisualProperty(DrawAsCircle); break; case ListPopupMenu::mt_ChangeToClass: - case ListPopupMenu::mt_ChangeToClass_Selection: changeToClass(); break; case ListPopupMenu::mt_ChangeToInterface: - case ListPopupMenu::mt_ChangeToInterface_Selection: changeToInterface(); break; diff -Nru umbrello-4.12.3/umbrello/widgets/classifierwidget.h umbrello-4.12.90/umbrello/widgets/classifierwidget.h --- umbrello-4.12.3/umbrello/widgets/classifierwidget.h 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/widgets/classifierwidget.h 2014-03-05 15:04:09.000000000 +0000 @@ -62,6 +62,7 @@ bool visualProperty(VisualProperty property) const; void setVisualProperty(VisualProperty property, bool enable = true); + void setVisualPropertyCmd(VisualProperty property, bool enable = true); void toggleVisualProperty(VisualProperty property); int displayedAttributes(); @@ -91,6 +92,7 @@ virtual bool loadFromXMI(QDomElement & qElement); virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0); + virtual QPainterPath shape() const; public Q_SLOTS: virtual void slotMenuSelection(QAction* action); @@ -105,7 +107,7 @@ QSizeF minimumSize(); - void drawAsCircle(QPainter *p); + void drawAsCircle(QPainter *p, const QStyleOptionGraphicsItem *option); QSize calculateAsCircleSize(); int displayedMembers(UMLObject::ObjectType ot); diff -Nru umbrello-4.12.3/umbrello/widgets/componentwidget.cpp umbrello-4.12.90/umbrello/widgets/componentwidget.cpp --- umbrello-4.12.3/umbrello/widgets/componentwidget.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/widgets/componentwidget.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -147,5 +147,11 @@ int height = (2*fontHeight) + (COMPONENT_MARGIN * 3); + UMLComponent *umlcomp = static_cast(m_umlObject); + if (umlcomp && umlcomp->getExecutable()) { + width += 2; + height += 2; + } + return QSizeF(width, height); } diff -Nru umbrello-4.12.3/umbrello/widgets/floatingdashlinewidget.cpp umbrello-4.12.90/umbrello/widgets/floatingdashlinewidget.cpp --- umbrello-4.12.3/umbrello/widgets/floatingdashlinewidget.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/widgets/floatingdashlinewidget.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -86,7 +86,7 @@ bool FloatingDashLineWidget::onLine(const QPointF& point) { // check if the given point is the start or end point of the line - if (((abs(y() + height() - point.y())) <= POINT_DELTA) || (abs(y() - point.y()) <= POINT_DELTA)) { + if (((abs((long)(y() + height() - point.y()))) <= POINT_DELTA) || (abs((long)(y() - point.y())) <= POINT_DELTA)) { return true; } // check if the given point is the start or end point of the line @@ -101,7 +101,7 @@ { bool ok = false; QString name = m_Text; - name = KInputDialog::getText(i18n("Enter alternative Name"), i18n("Enter the alternative :"), m_Text, &ok); + name = KInputDialog::getText(i18n("Enter alternative Name"), i18n("Enter the alternative:"), m_Text, &ok); if (ok && name.length() > 0) m_Text = name; } diff -Nru umbrello-4.12.3/umbrello/widgets/floatingtextwidget.cpp umbrello-4.12.90/umbrello/widgets/floatingtextwidget.cpp --- umbrello-4.12.3/umbrello/widgets/floatingtextwidget.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/widgets/floatingtextwidget.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -607,6 +607,8 @@ if(!UMLWidget::loadFromXMI(qElement)) return false; + m_unconstrainedPositionX = x(); + m_unconstrainedPositionY = y(); QString role = qElement.attribute("role", ""); if(!role.isEmpty()) m_textRole = Uml::TextRole::fromInt(role.toInt()); diff -Nru umbrello-4.12.3/umbrello/widgets/messagewidget.cpp umbrello-4.12.90/umbrello/widgets/messagewidget.cpp --- umbrello-4.12.3/umbrello/widgets/messagewidget.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/widgets/messagewidget.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -22,6 +22,7 @@ #include "umldoc.h" #include "umlview.h" #include "uniqueid.h" +#include "idchangelog.h" //qt includes #include @@ -57,7 +58,6 @@ init(); m_pOw[Uml::RoleType::A] = a; m_pOw[Uml::RoleType::B] = b; - m_nY = y; m_sequenceMessageType = sequenceMessageType; if (m_sequenceMessageType == Uml::SequenceMessage::Creation) { y -= m_pOw[Uml::RoleType::B]->height() / 2; @@ -67,7 +67,7 @@ calculateWidget(); y = y < getMinY() ? getMinY() : y; y = y > getMaxY() ? getMaxY() : y; - m_nY = y; + setY(y); this->activate(); } @@ -107,17 +107,15 @@ m_pOw[Uml::RoleType::B] = a; m_sequenceMessageType = sequenceMessageType; - m_nY = yclick; xclicked = xclick; yclicked = yclick; - m_nY = yclick; updateResizability(); calculateWidget(); yclick = yclick < getMinY() ? getMinY() : yclick; yclick = yclick > getMaxY() ? getMaxY() : yclick; - m_nY = yclick; + setY(yclick); yclicked = yclick; this->activate(); @@ -132,8 +130,6 @@ m_ignoreSnapComponentSizeToGrid = true; m_pOw[Uml::RoleType::A] = m_pOw[Uml::RoleType::B] = NULL; m_pFText = NULL; - m_nY = 0; - m_unconstrainedPositionY = 0; } /** @@ -151,13 +147,21 @@ */ void MessageWidget::setY(qreal y) { + if (y < getMinY()) { + DEBUG(DBG_SRC) << "got out of bounds y position, check the reason" << this->y() << getMinY(); + return; + } + UMLWidget::setY(y); - m_nY = y; if (m_sequenceMessageType == Uml::SequenceMessage::Creation) { const qreal objWidgetHalfHeight = m_pOw[Uml::RoleType::B]->height() / 2; m_pOw[Uml::RoleType::B]->setY(y - objWidgetHalfHeight); } - moveEvent(0); + + if (m_pFText) { + setTextPosition(); + emit sigMessageMoved(); + } } /** @@ -259,17 +263,7 @@ void MessageWidget::moveWidgetBy(qreal diffX, qreal diffY) { Q_UNUSED(diffX); - m_unconstrainedPositionY += diffY; qreal newY = constrainPositionY(diffY); - - if (m_unconstrainedPositionY != newY) { - if (m_unconstrainedPositionY > y()) { - newY = m_unconstrainedPositionY; - } else { - return; - } - } - setY(newY); } @@ -302,15 +296,15 @@ } setPenFromSettings(painter); if (m_sequenceMessageType == Uml::SequenceMessage::Synchronous) { - paintSynchronous(painter); + paintSynchronous(painter, option); } else if (m_sequenceMessageType == Uml::SequenceMessage::Asynchronous) { - paintAsynchronous(painter); + paintAsynchronous(painter, option); } else if (m_sequenceMessageType == Uml::SequenceMessage::Creation) { - paintCreation(painter); + paintCreation(painter, option); } else if (m_sequenceMessageType == Uml::SequenceMessage::Lost) { - paintLost(painter); + paintLost(painter, option); } else if (m_sequenceMessageType == Uml::SequenceMessage::Found) { - paintFound(painter); + paintFound(painter, option); } else { uWarning() << "Unknown message type"; } @@ -367,7 +361,7 @@ * timeline box and the returning arrow with a dashed line and * stick arrowhead. */ -void MessageWidget::paintSynchronous(QPainter *painter) +void MessageWidget::paintSynchronous(QPainter *painter, const QStyleOptionGraphicsItem *option) { int x1 = m_pOw[Uml::RoleType::A]->x(); int x2 = m_pOw[Uml::RoleType::B]->x(); @@ -425,13 +419,13 @@ paintArrow(painter, offsetX + wr + 1, offsetY + h - arrowWidth + 1, w - wr - 1, Qt::RightArrow, true); // return arrow } - UMLWidget::paint(painter, 0); + UMLWidget::paint(painter, option); } /** * Draws a solid arrow line and a stick arrow head. */ -void MessageWidget::paintAsynchronous(QPainter *painter) +void MessageWidget::paintAsynchronous(QPainter *painter, const QStyleOptionGraphicsItem *option) { int x1 = m_pOw[Uml::RoleType::A]->x(); int x2 = m_pOw[Uml::RoleType::B]->x(); @@ -473,7 +467,7 @@ paintArrow(painter, offsetX, offsetY + 4, w, Qt::LeftArrow); } - UMLWidget::paint(painter, 0); + UMLWidget::paint(painter, option); } /** @@ -481,7 +475,7 @@ * edge of the target object widget instead of to the * sequence line. */ -void MessageWidget::paintCreation(QPainter *painter) +void MessageWidget::paintCreation(QPainter *painter, const QStyleOptionGraphicsItem *option) { int x1 = m_pOw[Uml::RoleType::A]->x(); int x2 = m_pOw[Uml::RoleType::B]->x(); @@ -509,7 +503,7 @@ paintArrow(painter, offsetX, lineY, w, Qt::LeftArrow); } - UMLWidget::paint(painter, 0); + UMLWidget::paint(painter, option); } @@ -517,7 +511,7 @@ * Draws a solid arrow line and a stick arrow head * and a circle */ -void MessageWidget::paintLost(QPainter *painter) +void MessageWidget::paintLost(QPainter *painter, const QStyleOptionGraphicsItem *option) { int x1 = m_pOw[Uml::RoleType::A]->centerX(); int x2 = xclicked; @@ -549,13 +543,13 @@ paintArrow(painter, offsetX + h, offsetY + h/2, w - h, Qt::LeftArrow); } - UMLWidget::paint(painter, 0); + UMLWidget::paint(painter, option); } /** * Draws a circle and a solid arrow line and a stick arrow head. */ -void MessageWidget::paintFound(QPainter *painter) +void MessageWidget::paintFound(QPainter *painter, const QStyleOptionGraphicsItem *option) { int x1 = m_pOw[Uml::RoleType::A]->centerX(); int x2 = xclicked; @@ -588,7 +582,7 @@ paintArrow(painter, offsetX, offsetY + h/2, w, Qt::RightArrow); } - UMLWidget::paint(painter, 0); + UMLWidget::paint(painter, option); } /** @@ -704,22 +698,6 @@ } } -void MessageWidget::moveEvent(QGraphicsSceneMouseEvent* /*m*/) -{ - //DEBUG(DBG_SRC) << "m_pFText is " << m_pFText; - if (!m_pFText) { - return; - } - //TODO why this condition? -/* if (m_scene->selectedCount() > 2) { - return; - }*/ - - setTextPosition(); - - emit sigMessageMoved(); -} - void MessageWidget::resizeEvent(QResizeEvent* /*re*/) { } @@ -731,11 +709,7 @@ { setMessageText(m_pFText); calculateDimensions(); - setVisible(true); - - setX(m_nPosX); - UMLWidget::setY(m_nY); } void MessageWidget::slotWidgetMoved(Uml::ID::Type id) @@ -747,11 +721,12 @@ << ", idB=" << Uml::ID::toString(idB); return; } - m_nY = y(); - if (m_nY < getMinY()) - m_nY = getMinY(); - if (m_nY > getMaxY()) - m_nY = getMaxY(); + qreal y = this->y(); + if (y < getMinY()) + y = getMinY(); + if (y > getMaxY()) + y = getMaxY(); + setY(y); calculateWidget(); if(!m_pFText) return; @@ -877,6 +852,15 @@ } /** + * Resolve references of this message so they reference the correct + * new object widgets after paste. + */ +void MessageWidget::resolveObjectWidget(IDChangeLog* log) { + m_widgetAId = log->findNewID(m_widgetAId); + m_widgetBId = log->findNewID(m_widgetBId); +} + +/** * Overrides operation from LinkWidget. * Required by FloatingTextWidget. * @@ -1068,7 +1052,7 @@ widgetHeight = height(); } - m_nPosX = x; + setX(x); setSize(widgetWidth, widgetHeight); } @@ -1101,7 +1085,7 @@ } x += 1; widgetWidth -= 2; - m_nPosX = x; + setX(x); setSize(widgetWidth, widgetHeight); } @@ -1130,8 +1114,8 @@ } x += 1; widgetWidth -= 2; - m_nPosX = x; - m_nY = m_pOw[Uml::RoleType::B]->y() + m_pOw[Uml::RoleType::B]->height() / 2; + setX(x); + setY(m_pOw[Uml::RoleType::B]->y() + m_pOw[Uml::RoleType::B]->height() / 2); setSize(widgetWidth, widgetHeight); } @@ -1154,7 +1138,7 @@ x = x2 - circleWidth/2; widgetWidth = x1 - x2 + circleWidth/2; } - m_nPosX = x; + setX(x); setSize(widgetWidth, widgetHeight); } @@ -1178,7 +1162,7 @@ widgetWidth = x1 - x2 + circleWidth/2; } - m_nPosX = x; + setX(x); setSize(widgetWidth, widgetHeight); } @@ -1198,7 +1182,7 @@ UMLWidget::cleanup(); if (m_pFText) { - m_scene->removeWidget(m_pFText); + m_scene->removeWidgetCmd(m_pFText); m_pFText = NULL; } } @@ -1213,13 +1197,12 @@ UMLWidget::setSelected(_select); if(!m_pFText || m_pFText->displayText().isEmpty()) return; - if(m_selected && m_pFText->isSelected()) + if(isSelected() && m_pFText->isSelected()) return; - if(!m_selected && !m_pFText->isSelected()) + if(!isSelected() && !m_pFText->isSelected()) return; - m_scene->setSelected(m_pFText, 0); - m_pFText->setSelected(m_selected); + m_pFText->setSelected(isSelected()); } /** @@ -1369,7 +1352,6 @@ m_widgetAId = Uml::ID::fromString(widgetaid); m_widgetBId = Uml::ID::fromString(widgetbid); m_textId = Uml::ID::fromString(textid); - m_nY = y(); Uml::TextRole::Enum tr = Uml::TextRole::Seq_Message; if (m_widgetAId == m_widgetBId) diff -Nru umbrello-4.12.3/umbrello/widgets/messagewidget.h umbrello-4.12.90/umbrello/widgets/messagewidget.h --- umbrello-4.12.3/umbrello/widgets/messagewidget.h 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/widgets/messagewidget.h 2014-03-05 15:04:09.000000000 +0000 @@ -112,6 +112,7 @@ void calculateWidget(); virtual bool activate(IDChangeLog * Log = 0); + void resolveObjectWidget(IDChangeLog* log); void calculateDimensions(); void calculateDimensionsSynchronous(); @@ -166,11 +167,11 @@ void updateResizability(); - void paintSynchronous(QPainter *painter); - void paintAsynchronous(QPainter *painter); - void paintCreation(QPainter *painter); - void paintLost(QPainter *painter); - void paintFound(QPainter *painter); + void paintSynchronous(QPainter *painter, const QStyleOptionGraphicsItem *option); + void paintAsynchronous(QPainter *painter, const QStyleOptionGraphicsItem *option); + void paintCreation(QPainter *painter, const QStyleOptionGraphicsItem *option); + void paintLost(QPainter *painter, const QStyleOptionGraphicsItem *option); + void paintFound(QPainter *painter, const QStyleOptionGraphicsItem *option); // Data loaded/saved QString m_SequenceNumber; @@ -181,7 +182,6 @@ Uml::SequenceMessage::Enum m_sequenceMessageType; private: - void moveEvent(QGraphicsSceneMouseEvent *m); void resizeEvent(QResizeEvent *re); qreal constrainPositionY(qreal diffY); @@ -190,7 +190,6 @@ ObjectWidget * m_pOw[2]; FloatingTextWidget * m_pFText; - int m_nY; int xclicked; int yclicked; @@ -202,9 +201,6 @@ */ Uml::ID::Type m_widgetAId, m_widgetBId, m_textId; - /// The vertical position the widget would have if its move wasn't constrained. - qreal m_unconstrainedPositionY; - public slots: void slotWidgetMoved(Uml::ID::Type id); void slotMenuSelection(QAction* action); diff -Nru umbrello-4.12.3/umbrello/widgets/objectnodewidget.cpp umbrello-4.12.90/umbrello/widgets/objectnodewidget.cpp --- umbrello-4.12.3/umbrello/widgets/objectnodewidget.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/widgets/objectnodewidget.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -175,9 +175,8 @@ /** * Returns the type of object node. - * TODO: static, rename to "toObjectNodeType(...). */ -ObjectNodeWidget::ObjectNodeType ObjectNodeWidget::objectNodeType(const QString& type) const +ObjectNodeWidget::ObjectNodeType ObjectNodeWidget::toObjectNodeType(const QString& type) { if (type == "Central buffer") return ObjectNodeWidget::Buffer; @@ -204,7 +203,7 @@ */ void ObjectNodeWidget::setObjectNodeType(const QString& type) { - setObjectNodeType(ObjectNodeWidget::objectNodeType(type)); + setObjectNodeType(ObjectNodeWidget::toObjectNodeType(type)); } /** diff -Nru umbrello-4.12.3/umbrello/widgets/objectnodewidget.h umbrello-4.12.90/umbrello/widgets/objectnodewidget.h --- umbrello-4.12.3/umbrello/widgets/objectnodewidget.h 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/widgets/objectnodewidget.h 2014-03-05 15:04:09.000000000 +0000 @@ -44,7 +44,7 @@ virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0); ObjectNodeType objectNodeType() const; - ObjectNodeType objectNodeType(const QString& type) const; + static ObjectNodeType toObjectNodeType(const QString& type); void setObjectNodeType(ObjectNodeType objectNodeType); void setObjectNodeType(const QString& type) ; diff -Nru umbrello-4.12.3/umbrello/widgets/objectwidget.cpp umbrello-4.12.90/umbrello/widgets/objectwidget.cpp --- umbrello-4.12.3/umbrello/widgets/objectwidget.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/widgets/objectwidget.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -54,23 +54,19 @@ * @param o The object it will be representing. * @param lid The local id for the object. */ -ObjectWidget::ObjectWidget(UMLScene * scene, UMLObject *o, Uml::ID::Type lid) +ObjectWidget::ObjectWidget(UMLScene * scene, UMLObject *o) : UMLWidget(scene, WidgetBase::wt_Object, o), m_multipleInstance(false), m_drawAsActor(false), m_showDestruction(false), m_isOnDestructionBox(false) { - m_nLocalID = Uml::ID::None; if (m_scene && (m_scene->type() == Uml::DiagramType::Sequence)) { m_pLine = new SeqLineWidget( m_scene, this ); m_pLine->setStartPoint(x() + width() / 2, y() + height()); } else { m_pLine = 0; } - if (lid != Uml::ID::None) { - m_nLocalID = lid; - } } /** @@ -81,28 +77,6 @@ } /** - * Sets the local id of the object. - * - * @param id The local id of the object. - */ -void ObjectWidget::setLocalID(Uml::ID::Type id) -{ - m_nLocalID = id; -} - -/** - * Returns the local ID for this object. This ID is used so that - * many objects of the same @ref UMLObject instance can be on the - * same diagram. - * - * @return The local ID. - */ -Uml::ID::Type ObjectWidget::localID() const -{ - return m_nLocalID; -} - -/** * Sets whether representing a multi-instance object. * * @param multiple Object state. true- multi, false - single. @@ -501,7 +475,6 @@ if (newY < topMargin()) newY = topMargin(); setY(newY); - moveEvent(0); adjustAssocs(x(), newY); } @@ -512,7 +485,6 @@ { int newY = y() + height(); setY(newY); - moveEvent(0); adjustAssocs(x(), newY); } @@ -699,7 +671,6 @@ UMLWidget::saveToXMI(qDoc, objectElement); objectElement.setAttribute("drawasactor", m_drawAsActor); objectElement.setAttribute("multipleinstance", m_multipleInstance); - objectElement.setAttribute("localid", Uml::ID::toString(m_nLocalID)); objectElement.setAttribute("decon", m_showDestruction); qElement.appendChild(objectElement); } @@ -713,12 +684,10 @@ return false; QString draw = qElement.attribute("drawasactor", "0"); QString multi = qElement.attribute("multipleinstance", "0"); - QString localid = qElement.attribute("localid", "0"); QString decon = qElement.attribute("decon", "0"); m_drawAsActor = (bool)draw.toInt(); m_multipleInstance = (bool)multi.toInt(); - m_nLocalID = Uml::ID::fromString(localid); m_showDestruction = (bool)decon.toInt(); return true; } diff -Nru umbrello-4.12.3/umbrello/widgets/objectwidget.h umbrello-4.12.90/umbrello/widgets/objectwidget.h --- umbrello-4.12.3/umbrello/widgets/objectwidget.h 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/widgets/objectwidget.h 2014-03-05 15:04:09.000000000 +0000 @@ -33,7 +33,7 @@ { Q_OBJECT public: - ObjectWidget(UMLScene *scene, UMLObject *o, Uml::ID::Type lid = Uml::ID::None); + ObjectWidget(UMLScene *scene, UMLObject *o); virtual ~ObjectWidget(); virtual void setX(qreal x); @@ -41,9 +41,6 @@ qreal centerX(); - void setLocalID(Uml::ID::Type id); - Uml::ID::Type localID() const; - void setMultipleInstance(bool multiple); bool multipleInstance() const; @@ -107,7 +104,6 @@ void moveDestructionBy(qreal diffY); SeqLineWidget* m_pLine; - Uml::ID::Type m_nLocalID; ///< local ID used on views bool m_multipleInstance; ///< draw an object as a multiple object bool m_drawAsActor; ///< object should be drawn as an Actor or an Object bool m_showDestruction; ///< show object destruction on sequence diagram line diff -Nru umbrello-4.12.3/umbrello/widgets/preconditionwidget.cpp umbrello-4.12.90/umbrello/widgets/preconditionwidget.cpp --- umbrello-4.12.3/umbrello/widgets/preconditionwidget.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/widgets/preconditionwidget.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -18,6 +18,7 @@ #include "uml.h" #include "umlscene.h" #include "uniqueid.h" +#include "idchangelog.h" // kde includes #include @@ -150,8 +151,12 @@ { m_scene->resetPastePoint(); UMLWidget::activate(Log); - if (m_objectWidget == NULL) { - DEBUG(DBG_SRC) << "cannot make precondition"; + + loadObjectWidget(); + + if (!m_objectWidget) { + DEBUG(DBG_SRC) << "role A widget " << Uml::ID::toString(m_widgetAId) + << " could not be found"; return false; } @@ -162,6 +167,14 @@ } /** + * Resolve references of this precondition so it references the correct + * new object widget after paste. + */ +void PreconditionWidget::resolveObjectWidget(IDChangeLog* log) { + m_widgetAId = log->findNewID(m_widgetAId); +} + +/** * Calculates the size of the widget. */ void PreconditionWidget::calculateDimensions() @@ -283,15 +296,28 @@ setName(qElement.attribute("preconditionname", "")); setDocumentation(qElement.attribute("documentation", "")); - Uml::ID::Type aId = Uml::ID::fromString(widgetaid); + m_widgetAId = Uml::ID::fromString(widgetaid); - m_objectWidget = dynamic_cast(umlScene()->findWidget(aId)); - if (!m_objectWidget) { - DEBUG(DBG_SRC) << "role A widget " << Uml::ID::toString(aId) << " is not an ObjectWidget"; - return false; - } + // Lookup the ObjectWidget, if it can't be found, assume it will be + // resolved later + loadObjectWidget(); return true; } +/** + * Load the object widget from m_widgetAId + * + * This method is called in loadFromXMI() when loading an XMI file, and called + * from activate() when activating a widget after pasting. + */ +void PreconditionWidget::loadObjectWidget() +{ + if (m_objectWidget == 0) { + m_objectWidget = dynamic_cast( + umlScene()->findWidget(m_widgetAId) + ); + } +} + #include "preconditionwidget.moc" diff -Nru umbrello-4.12.3/umbrello/widgets/preconditionwidget.h umbrello-4.12.90/umbrello/widgets/preconditionwidget.h --- umbrello-4.12.3/umbrello/widgets/preconditionwidget.h 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/widgets/preconditionwidget.h 2014-03-05 15:04:09.000000000 +0000 @@ -42,10 +42,13 @@ int maxY() const; bool activate(IDChangeLog* Log = 0); + void resolveObjectWidget(IDChangeLog* log); virtual void saveToXMI(QDomDocument& qDoc, QDomElement& qElement); virtual bool loadFromXMI(QDomElement& qElement); + void setObjectWidget(ObjectWidget* widget); + public slots: void slotMenuSelection(QAction* action); void slotWidgetMoved(Uml::ID::Type id); @@ -59,6 +62,9 @@ ObjectWidget* m_objectWidget; int m_nY; + + Uml::ID::Type m_widgetAId; + void loadObjectWidget(); }; #endif diff -Nru umbrello-4.12.3/umbrello/widgets/umlwidget.cpp umbrello-4.12.90/umbrello/widgets/umlwidget.cpp --- umbrello-4.12.3/umbrello/widgets/umlwidget.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/widgets/umlwidget.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -113,7 +113,6 @@ setRect(rect().x(), rect().y(), other.width(), other.height()); // assign volatile (non-saved) members - m_selected = other.m_selected; m_startMove = other.m_startMove; m_nPosX = other.m_nPosX; m_doc = other.m_doc; //new @@ -178,6 +177,28 @@ } /** + * Sets the local id of the object. + * + * @param id The local id of the object. + */ +void UMLWidget::setLocalID(Uml::ID::Type id) +{ + m_nLocalID = id; +} + +/** + * Returns the local ID for this object. This ID is used so that + * many objects of the same @ref UMLObject instance can be on the + * same diagram. + * + * @return The local ID. + */ +Uml::ID::Type UMLWidget::localID() const +{ + return m_nLocalID; +} + +/** * Compute the minimum possible width and height. * * @return QSizeF(mininum_width, minimum_height) @@ -301,92 +322,6 @@ } /** - * Handles a mouse move event. - * It resizes or moves the widget, depending on where the cursor is pressed - * on the widget. Go on reading for more info about this. - * - * If resizing, the widget is resized using UMLWidget::resizeWidget (where specific - * widget resize constrain can be applied), and then the associations are - * adjusted. - * The resizing can be constrained also to an specific axis using control - * and shift buttons. If on or another is pressed, it's constrained to X axis. - * If both are pressed, it's constrained to Y axis. - * - * If not resizing, the widget is being moved. If the move is being started, - * the selection bounds are set (which includes updating the list of selected - * widgets). - * The difference between the previous position of the selection and the new - * one is got (taking in account the selection bounds so widgets don't go - * beyond the scene limits). Then, it's constrained to X or Y axis depending - * on shift and control buttons. - * A further constrain is made using constrainMovementForAllWidgets (for example, - * if the widget that receives the event can only be moved in Y axis, with this - * method the movement of all the widgets in the selection can be constrained to - * be moved only in Y axis). - * Then, all the selected widgets are moved using moveWidgetBy (where specific - * widget movement constrain can be applied) and, if an specific amount of time - * passed from the last move event, the associations are also updated (they're - * not updated always to be easy on the CPU). Finally, the scene is resized, - * and selection bounds updated. - * - * @param me The QGraphicsSceneMouseEvent event. - */ -void UMLWidget::mouseMoveEvent(QGraphicsSceneMouseEvent* me) -{ - if (m_inResizeArea) { - resize(me); - return; - } - - if (!m_moved) { - UMLApp::app()->document()->writeToStatusBar(i18n("Hold shift or ctrl to move in X axis. Hold shift and control to move in Y axis. Right button click to cancel move.")); - - m_moved = true; - //Maybe needed by AssociationWidget - m_startMove = true; - - setSelectionBounds(); - } - - QPointF position = me->scenePos() - m_pressOffset; - qreal diffX = position.x() - x(); - qreal diffY = position.y() - y(); - - if ((me->modifiers() & Qt::ShiftModifier) && (me->modifiers() & Qt::ControlModifier)) { - // move only in Y axis - diffX = 0; - } else if ((me->modifiers() & Qt::ShiftModifier) || (me->modifiers() & Qt::ControlModifier)) { - // move only in X axis - diffY = 0; - } - - constrainMovementForAllWidgets(diffX, diffY); - - // nothing to move - if (diffX == 0 && diffY == 0) { - return; - } - - QPointF delta = me->scenePos() - me->lastScenePos(); - adjustUnselectedAssocs(delta.x(), delta.y()); - - DEBUG(DBG_SRC) << "diffX=" << diffX << " / diffY=" << diffY; - foreach(UMLWidget* widget, m_selectedWidgetsList) { - widget->moveWidgetBy(diffX, diffY); - widget->slotSnapToGrid(); - } - - // Move any selected associations. - foreach(AssociationWidget* aw, m_scene->selectedAssocs()) { - if (aw->isSelected()) { - aw->moveEntireAssoc(diffX, diffY); - } - } - - umlScene()->resizeSceneToItems(); -} - -/** * Handles a mouse press event. * It'll select the widget (or mark it to be deselected) and prepare it to * be moved or resized. Go on reading for more info about this. @@ -411,7 +346,7 @@ * it's marked to be deselected when releasing the button (provided it wasn't * moved or resized). * - * @param me The QGraphicsSceneMouseEvent event. + * @param event The QGraphicsSceneMouseEvent event. */ void UMLWidget::mousePressEvent(QGraphicsSceneMouseEvent *event) { @@ -473,6 +408,92 @@ } /** + * Handles a mouse move event. + * It resizes or moves the widget, depending on where the cursor is pressed + * on the widget. Go on reading for more info about this. + * + * If resizing, the widget is resized using UMLWidget::resizeWidget (where specific + * widget resize constrain can be applied), and then the associations are + * adjusted. + * The resizing can be constrained also to an specific axis using control + * and shift buttons. If on or another is pressed, it's constrained to X axis. + * If both are pressed, it's constrained to Y axis. + * + * If not resizing, the widget is being moved. If the move is being started, + * the selection bounds are set (which includes updating the list of selected + * widgets). + * The difference between the previous position of the selection and the new + * one is got (taking in account the selection bounds so widgets don't go + * beyond the scene limits). Then, it's constrained to X or Y axis depending + * on shift and control buttons. + * A further constrain is made using constrainMovementForAllWidgets (for example, + * if the widget that receives the event can only be moved in Y axis, with this + * method the movement of all the widgets in the selection can be constrained to + * be moved only in Y axis). + * Then, all the selected widgets are moved using moveWidgetBy (where specific + * widget movement constrain can be applied) and, if an specific amount of time + * passed from the last move event, the associations are also updated (they're + * not updated always to be easy on the CPU). Finally, the scene is resized, + * and selection bounds updated. + * + * @param event The QGraphicsSceneMouseEvent event. + */ +void UMLWidget::mouseMoveEvent(QGraphicsSceneMouseEvent* event) +{ + if (m_inResizeArea) { + resize(event); + return; + } + + if (!m_moved) { + UMLApp::app()->document()->writeToStatusBar(i18n("Hold shift or ctrl to move in X axis. Hold shift and control to move in Y axis. Right button click to cancel move.")); + + m_moved = true; + //Maybe needed by AssociationWidget + m_startMove = true; + + setSelectionBounds(); + } + + QPointF position = event->scenePos() - m_pressOffset; + qreal diffX = position.x() - x(); + qreal diffY = position.y() - y(); + + if ((event->modifiers() & Qt::ShiftModifier) && (event->modifiers() & Qt::ControlModifier)) { + // move only in Y axis + diffX = 0; + } else if ((event->modifiers() & Qt::ShiftModifier) || (event->modifiers() & Qt::ControlModifier)) { + // move only in X axis + diffY = 0; + } + + constrainMovementForAllWidgets(diffX, diffY); + + // nothing to move + if (diffX == 0 && diffY == 0) { + return; + } + + QPointF delta = event->scenePos() - event->lastScenePos(); + adjustUnselectedAssocs(delta.x(), delta.y()); + + DEBUG(DBG_SRC) << "diffX=" << diffX << " / diffY=" << diffY; + foreach(UMLWidget* widget, umlScene()->selectedWidgets()) { + widget->moveWidgetBy(diffX, diffY); + widget->slotSnapToGrid(); + } + + // Move any selected associations. + foreach(AssociationWidget* aw, m_scene->selectedAssocs()) { + if (aw->isSelected()) { + aw->moveEntireAssoc(diffX, diffY); + } + } + + umlScene()->resizeSceneToItems(); +} + +/** * Handles a mouse release event. * It selects or deselects the widget and cancels or confirms the move or * resize. Go on reading for more info about this. @@ -493,22 +514,29 @@ * event at the same position than the cursor was when pressed. Another left * button release is also sent. * - * @param me The QGraphicsSceneMouseEvent event. + * @param event The QGraphicsSceneMouseEvent event. */ -void UMLWidget::mouseReleaseEvent(QGraphicsSceneMouseEvent *me) +void UMLWidget::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { if (!m_moved && !m_resized) { if (!m_shiftPressed && (m_scene->selectedCount(true) > 1)) { - selectSingle(me); + selectSingle(event); } else if (!isSelected()) { - deselect(me); + deselect(event); } } else { // Commands if (m_moved) { - foreach(UMLWidget* widget, m_selectedWidgetsList) { + int selectionCount = umlScene()->selectedWidgets().count(); + if (selectionCount > 1) { + UMLApp::app()->beginMacro(i18n("Move widgets")); + } + foreach(UMLWidget* widget, umlScene()->selectedWidgets()) { UMLApp::app()->executeCommand(new Uml::CmdMoveWidget(widget)); } + if (selectionCount > 1) { + UMLApp::app()->endMacro(); + } m_moved = false; } else { UMLApp::app()->executeCommand(new Uml::CmdResizeWidget(this)); @@ -640,14 +668,15 @@ void UMLWidget::init() { m_nId = Uml::ID::None; + m_nLocalID = UniqueID::gen(); m_isInstance = false; setMinimumSize(DefaultMinimumSize); setMaximumSize(DefaultMaximumSize); - + for (int i = 0; i < (int)FT_INVALID; ++i) { m_pFontMetrics[(UMLWidget::FontType)i] = 0; } - + if (m_scene) { m_useFillColor = true; m_usesDiagramFillColor = true; @@ -666,7 +695,6 @@ m_resizable = true; m_fixedAspectRatio = false; - m_selected = false; m_startMove = false; m_activated = false; m_ignoreSnapToGrid = false; @@ -712,10 +740,6 @@ ListPopupMenu::MenuType sel = ListPopupMenu::typeFromAction(trigger); switch (sel) { - case ListPopupMenu::mt_Delete: - umlScene()->removeWidget(this); - break; - case ListPopupMenu::mt_Resize: umlScene()->resizeSelection(); break; @@ -806,12 +830,24 @@ } /** - * Set the status of using fill color. + * Set the status of using fill color (undo action) * * @param fc the status of using fill color. */ void UMLWidget::setUseFillColor(bool fc) { + if (useFillColor() != fc) { + UMLApp::app()->executeCommand(new CmdChangeUseFillColor(this, fc)); + } +} + +/** + * Set the status of using fill color. + * + * @param fc the status of using fill color. + */ +void UMLWidget::setUseFillColorCmd(bool fc) +{ WidgetBase::setUseFillColor(fc); update(); } @@ -819,7 +855,7 @@ /** * Overrides the method from WidgetBase. */ -void UMLWidget::setTextColorcmd(const QColor &color) +void UMLWidget::setTextColorCmd(const QColor &color) { WidgetBase::setTextColor(color); update(); @@ -830,14 +866,16 @@ */ void UMLWidget::setTextColor(const QColor &color) { - UMLApp::app()->executeCommand(new CmdChangeTextColor(this, color)); - update(); + if (textColor() != color) { + UMLApp::app()->executeCommand(new CmdChangeTextColor(this, color)); + update(); + } } /** * Overrides the method from WidgetBase. */ -void UMLWidget::setLineColorcmd(const QColor &color) +void UMLWidget::setLineColorCmd(const QColor &color) { WidgetBase::setLineColor(color); update(); @@ -848,14 +886,26 @@ */ void UMLWidget::setLineColor(const QColor &color) { - UMLApp::app()->executeCommand(new CmdChangeLineColor(this, color)); + if (lineColor() != color) { + UMLApp::app()->executeCommand(new CmdChangeLineColor(this, color)); + } } /** - * Overrides the method from WidgetBase. + * Overrides the method from WidgetBase, execute CmdChangeLineWidth */ void UMLWidget::setLineWidth(uint width) { + if (lineWidth() != width) { + UMLApp::app()->executeCommand(new CmdChangeLineWidth(this, width)); + } +} + +/** + * Overrides the method from WidgetBase. + */ +void UMLWidget::setLineWidthCmd(uint width) +{ WidgetBase::setLineWidth(width); update(); } @@ -867,7 +917,9 @@ */ void UMLWidget::setFillColor(const QColor &color) { - UMLApp::app()->executeCommand(new CmdChangeFillColor(this, color)); + if (fillColor() != color) { + UMLApp::app()->executeCommand(new CmdChangeFillColor(this, color)); + } } /** @@ -875,7 +927,7 @@ * * @param color the new fill color */ -void UMLWidget::setFillColorcmd(const QColor &color) +void UMLWidget::setFillColorCmd(const QColor &color) { WidgetBase::setFillColor(color); update(); @@ -896,7 +948,7 @@ return false; } } - setFont(m_font); + setFontCmd(m_font); setSize(width(), height()); m_activated = true; updateGeometry(); @@ -1239,10 +1291,11 @@ */ void UMLWidget::setSelectionBounds() { - if (m_scene->selectedCount() > 0) { - m_selectedWidgetsList.clear(); - m_selectedWidgetsList = m_scene->selectedWidgetsExt(false); - } +} + +void UMLWidget::setSelectedFlag(bool _select) +{ + WidgetBase::setSelected(_select); } /** @@ -1252,6 +1305,7 @@ */ void UMLWidget::setSelected(bool _select) { + WidgetBase::setSelected(_select); const WidgetBase::WidgetType wt = m_baseType; if (_select) { if (m_scene->selectedCount() == 0) { @@ -1268,11 +1322,11 @@ /* if (wt != wt_Text && wt != wt_Box) { setZ(m_origZ); } */ - if (m_selected) + if (isSelected()) UMLApp::app()->docWindow()->updateDocumentation(true); } - m_selected = _select; + // TODO: isn't this handled by toForeground() ? const QPoint pos(x(), y()); UMLWidget *bkgnd = m_scene->widgetAt(pos); if (bkgnd && bkgnd != this && _select) { @@ -1316,8 +1370,9 @@ */ void UMLWidget::selectMultiple(QGraphicsSceneMouseEvent *me) { + Q_UNUSED(me); + setSelected(true); - m_scene->setSelected(this, me); } /** @@ -1327,8 +1382,9 @@ */ void UMLWidget::deselect(QGraphicsSceneMouseEvent *me) { + Q_UNUSED(me); + setSelected(false); - m_scene->setSelected(this, me); } /** @@ -1401,7 +1457,7 @@ if (!m_ignoreSnapToGrid) { qreal newX = m_scene->snappedX(x()); setX(newX); - qreal newY = m_scene->snappedX(y()); + qreal newY = m_scene->snappedY(y()); setY(newY); } } @@ -1509,10 +1565,10 @@ /** * Template Method, override this to set the default font metric. */ -void UMLWidget::setDefaultFontMetrics(UMLWidget::FontType fontType) +void UMLWidget::setDefaultFontMetrics(QFont &font, UMLWidget::FontType fontType) { - setupFontType(m_font, fontType); - setFontMetrics(fontType, QFontMetrics(m_font)); + setupFontType(font, fontType); + setFontMetrics(fontType, QFontMetrics(font)); } void UMLWidget::setupFontType(QFont &font, UMLWidget::FontType fontType) @@ -1567,7 +1623,7 @@ Q_UNUSED(option); Q_UNUSED(widget); - if (m_selected) { + if (option->state & QStyle::State_Selected) { const qreal w = width(); const qreal h = height(); const qreal s = 4; @@ -1589,6 +1645,17 @@ } else { painter->fillRect(0 + w - s, 0 + h - s, s, s, brush); } + // debug info + if (Tracer::instance()->isEnabled(metaObject()->className())) { + painter->setPen(Qt::green); + painter->setBrush(Qt::NoBrush); + painter->drawPath(shape()); + painter->setPen(Qt::red); + painter->drawRect(boundingRect()); + // origin + painter->drawLine(-10, 0, 10, 0); + painter->drawLine(0, -10, 0, 10); + } } if (umlScene()->isShowDocumentationIndicator() && hasDocumentation()) { @@ -1605,10 +1672,10 @@ /** * Template Method, override this to set the default font metric. */ -void UMLWidget::setDefaultFontMetrics(UMLWidget::FontType fontType, QPainter &painter) +void UMLWidget::setDefaultFontMetrics(QFont &font, UMLWidget::FontType fontType, QPainter &painter) { - setupFontType(m_font, fontType); - painter.setFont(m_font); + setupFontType(font, fontType); + painter.setFont(font); setFontMetrics(fontType, painter.fontMetrics()); } @@ -1619,7 +1686,7 @@ QFontMetrics &UMLWidget::getFontMetrics(UMLWidget::FontType fontType) { if (m_pFontMetrics[fontType] == 0) { - setDefaultFontMetrics(fontType); + setDefaultFontMetrics(m_font, fontType); } return *m_pFontMetrics[fontType]; } @@ -1640,6 +1707,21 @@ */ void UMLWidget::setFont(const QFont &font) { + QFont newFont = font; + forceUpdateFontMetrics(newFont, 0); + + if (m_font != newFont) { + UMLApp::app()->executeCommand(new CmdChangeFont(this, font)); + } +} + +/** + * Sets the font the widget is to use. + * + * @param font Font to be set. + */ +void UMLWidget::setFontCmd(const QFont &font) +{ WidgetBase::setFont(font); forceUpdateFontMetrics(0); if (m_doc->loading()) @@ -1648,23 +1730,31 @@ } /** + * Updates font metrics for widgets current m_font + */ +void UMLWidget::forceUpdateFontMetrics(QPainter *painter) +{ + forceUpdateFontMetrics(m_font, painter); +} + +/** * @note For performance Reasons, only FontMetrics for already used * font types are updated. Not yet used font types will not get a font metric * and will get the same font metric as if painter was zero. * This behaviour is acceptable, because diagrams will always be showed on Display * first before a special painter like a printer device is used. */ -void UMLWidget::forceUpdateFontMetrics(QPainter *painter) +void UMLWidget::forceUpdateFontMetrics(QFont& font, QPainter *painter) { if (painter == 0) { for (int i = 0; i < (int)UMLWidget::FT_INVALID; ++i) { if (m_pFontMetrics[(UMLWidget::FontType)i] != 0) - setDefaultFontMetrics((UMLWidget::FontType)i); + setDefaultFontMetrics(font, (UMLWidget::FontType)i); } } else { for (int i2 = 0; i2 < (int)UMLWidget::FT_INVALID; ++i2) { if (m_pFontMetrics[(UMLWidget::FontType)i2] != 0) - setDefaultFontMetrics((UMLWidget::FontType)i2, *painter); + setDefaultFontMetrics(font, (UMLWidget::FontType)i2, *painter); } } if (m_doc->loading()) @@ -1721,6 +1811,10 @@ qElement.setAttribute("instancename", m_instanceName); if (m_showStereotype) qElement.setAttribute("showstereotype", m_showStereotype); + + // Unique identifier for widget (todo: id() should be unique, new attribute + // should indicate the UMLObject's ID it belongs to) + qElement.setAttribute("localid", Uml::ID::toString(m_nLocalID)); } bool UMLWidget::loadFromXMI(QDomElement & qElement) @@ -1742,6 +1836,12 @@ m_instanceName = qElement.attribute("instancename", ""); QString showstereo = qElement.attribute("showstereotype", "0"); m_showStereotype = (bool)showstereo.toInt(); + + QString localid = qElement.attribute("localid", "0"); + if (localid != "0") { + m_nLocalID = Uml::ID::fromString(localid); + } + return true; } diff -Nru umbrello-4.12.3/umbrello/widgets/umlwidget.h umbrello-4.12.90/umbrello/widgets/umlwidget.h --- umbrello-4.12.3/umbrello/widgets/umlwidget.h 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/widgets/umlwidget.h 2014-03-05 15:04:09.000000000 +0000 @@ -58,40 +58,33 @@ bool operator==(const UMLWidget& other) const; + void setLocalID(Uml::ID::Type id); + Uml::ID::Type localID() const; + virtual QSizeF minimumSize(); void setMinimumSize(const QSizeF &size); virtual QSizeF maximumSize(); void setMaximumSize(const QSizeF &size); - void setUseFillColor(bool fc); + virtual void setUseFillColor(bool fc); + void setUseFillColorCmd(bool fc); virtual void setTextColor(const QColor &color); - void setTextColorcmd(const QColor &color); + void setTextColorCmd(const QColor &color); virtual void setLineColor(const QColor &color); - void setLineColorcmd(const QColor &color); + void setLineColorCmd(const QColor &color); virtual void setLineWidth(uint width); + void setLineWidthCmd(uint width); virtual void setFillColor(const QColor &color); - void setFillColorcmd(const QColor &color); + void setFillColorCmd(const QColor &color); + void setSelectedFlag(bool _select); virtual void setSelected(bool _select); - /** - * Returns the state of whether the widget is selected. - * - * @return Returns the state of whether the widget is selected. - */ - bool isSelected() const { - return m_selected; - } - - void setSelectedFlag(bool _select) { - m_selected = _select; - } - void setScene(UMLScene *scene); virtual bool activate(IDChangeLog* ChangeLog = 0); @@ -102,6 +95,7 @@ void setPenFromSettings(QPainter *p); virtual void setFont(const QFont &font); + void setFontCmd(const QFont &font); /** * Returns whether we triggered the update of position movement. @@ -198,6 +192,7 @@ void clipSize(); void forceUpdateFontMetrics(QPainter *painter); + void forceUpdateFontMetrics(QFont &font, QPainter *painter); virtual bool loadFromXMI(QDomElement &qElement); virtual void saveToXMI(QDomDocument &qDoc, QDomElement &qElement); @@ -228,8 +223,8 @@ FT_INVALID = 8 } FontType; - virtual void setDefaultFontMetrics(UMLWidget::FontType fontType); - virtual void setDefaultFontMetrics(UMLWidget::FontType fontType, QPainter &painter); + virtual void setDefaultFontMetrics(QFont &font, UMLWidget::FontType fontType); + virtual void setDefaultFontMetrics(QFont &font, UMLWidget::FontType fontType, QPainter &painter); QFontMetrics &getFontMetrics(UMLWidget::FontType fontType); void setFontMetrics(UMLWidget::FontType fontType, QFontMetrics fm); @@ -259,8 +254,8 @@ protected: virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent* event); virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event); - virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event); virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event); virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); virtual void moveEvent(QGraphicsSceneMouseEvent *event); @@ -294,7 +289,8 @@ ///////////////// End of Data Loaded/Saved ////////////////////////// - bool m_selected, m_startMove; + Uml::ID::Type m_nLocalID; + bool m_startMove; QPointF m_startMovePostion; QSizeF m_startResizeSize; int m_nPosX; @@ -314,15 +310,6 @@ bool m_ignoreSnapComponentSizeToGrid; bool m_fixedAspectRatio; - /** - * A list containing the selected widgets. - * It's filled by setSelectionBounds method. It must be filled again if - * selected widgets changed. It is cleared only in setSelectionBounds, just - * before filling it. - * Select, deselect and so on methods DON'T modify this list. - */ - UMLWidgetList m_selectedWidgetsList; - /// The text in the status bar when the cursor was pressed. QString m_oldStatusBarMsg; diff -Nru umbrello-4.12.3/umbrello/widgets/widgetbase.cpp umbrello-4.12.90/umbrello/widgets/widgetbase.cpp --- umbrello-4.12.3/umbrello/widgets/widgetbase.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/widgets/widgetbase.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -45,9 +45,11 @@ m_usesDiagramLineColor(true), m_usesDiagramLineWidth(true) { + setSelected(false); scene->addItem(this); // TODO 310283 + setFlags(ItemIsSelectable); //setFlags(ItemIsSelectable | ItemIsMovable |ItemSendsGeometryChanges); if (m_scene) { m_usesDiagramLineColor = true; @@ -86,6 +88,16 @@ return QLatin1String(ENUM_NAME(WidgetBase, WidgetType, m_baseType)); } +/* + * Sets the state of whether the widget is selected. + * + * @param select The state of whether the widget is selected. + */ +void WidgetBase::setSelected(bool select) +{ + QGraphicsObject::setSelected(select); +} + /** * Deliver a pointer to the connected UMLView * (needed esp. by event handling of AssociationLine). @@ -559,7 +571,7 @@ if (!font.isEmpty()) { QFont newFont; newFont.fromString(font); - setFont(newFont); + m_font = newFont; } else { uWarning() << "Using default font " << m_font.toString() << " for widget with xmi.id " << Uml::ID::toString(m_nId); @@ -590,6 +602,7 @@ m_usesDiagramLineColor = other.m_usesDiagramLineColor; m_usesDiagramFillColor = other.m_usesDiagramFillColor; m_usesDiagramLineWidth = other.m_usesDiagramLineWidth; + setSelected(other.isSelected()); return *this; } @@ -654,15 +667,37 @@ uDebug() << "widget = " << name() << " / type = " << baseTypeStr(); UMLScene *scene = umlScene(); - if (!isSelected() && scene && !scene->selectedItems().isEmpty()) { + + // If right-click was done on a widget that was not selected, clear the + // current selection and select the new widget. The context menu is shown + // with actions for that single widget. + // If a keyboard modifier was used, add the widget to the current selection + // and show the menu with actions for the whole selection. + if (!isSelected()) { Qt::KeyboardModifiers forSelection = (Qt::ControlModifier | Qt::ShiftModifier); if ((event->modifiers() & forSelection) == 0) { - scene->clearSelection(); + scene->clearSelected(); + } + + if (umlObject() != 0) { + scene->selectWidget(dynamic_cast(this)); + } else { + setSelected(true); } } - setSelected(true); - ListPopupMenu popup(0, this, false, false); - setupContextMenuActions(popup); + + int count = scene->selectedCount(true); + + // Determine multi state + bool multi = (isSelected() && count > 1); + + ListPopupMenu popup(0, this, multi, scene->getUniqueSelectionType()); + + // Disable the "view code" menu for simple code generators + if (UMLApp::app()->isSimpleCodeGeneratorActive()) { + popup.setActionEnabled(ListPopupMenu::mt_ViewCode, false); + } + QAction *triggered = popup.exec(event->screenPos()); ListPopupMenu *parentMenu = ListPopupMenu::menuFromAction(triggered); @@ -682,38 +717,6 @@ } /** - * - */ -void WidgetBase::setupContextMenuActions(ListPopupMenu &menu) -{ -/* the following was code from UMLWidget::setupPopupMenu(): - //if in a multi- selection to a specific m_pMenu for that - // NEW: ask UMLView to count ONLY the widgets and not their floatingtextwidgets - int count = m_scene->selectedCount(true); - //a MessageWidget when selected will select its text widget and vice versa - //so take that into account for popup menu. - - // determine multi state - bool multi = (m_selected && count > 1); - - // if multiple selected items have the same type - bool unique = false; - - // if multiple items are selected, we have to check if they all have the same - // base type - if (multi == true) - unique = m_scene->checkUniqueSelection(); - - // create the right click context menu - m_pMenu = new ListPopupMenu(m_scene->activeView(), this, multi, unique); -*/ - - // disable the "view code" menu for simple code generators - if (UMLApp::app()->isSimpleCodeGeneratorActive()) - menu.setActionEnabled(ListPopupMenu::mt_ViewCode, false); -} - -/** * This is usually called synchronously after menu.exec() and \a * trigger's parent is always the ListPopupMenu which can be used to * get the type of action of \a trigger. @@ -726,8 +729,7 @@ if (!trigger) { return; } - QColor newColour; - WidgetBase* widget = 0; // use for select the first object properties (fill, line color) + QColor newColor; const WidgetType wt = m_baseType; // short hand name @@ -737,10 +739,6 @@ umlDoc()->renameUMLObject(umlObject()); break; - //case ListPopupMenu::mt_Delete: // is done in UMLWidget - // umlScene()->removeWidget(this); - // break; - case ListPopupMenu::mt_Properties: if (wt == WidgetBase::wt_Actor || wt == WidgetBase::wt_UseCase || wt == WidgetBase::wt_Package || wt == WidgetBase::wt_Interface || @@ -759,45 +757,101 @@ break; case ListPopupMenu::mt_Line_Color: - widget = umlScene()->getFirstMultiSelectedWidget(); - if (widget) { - newColour = widget->lineColor(); - } - if (KColorDialog::getColor(newColour)) { - umlScene()->selectionSetLineColor(newColour); + case ListPopupMenu::mt_Line_Color_Selection: + newColor = lineColor(); + if (KColorDialog::getColor(newColor)) { + if (sel == ListPopupMenu::mt_Line_Color_Selection) { + umlScene()->selectionSetLineColor(newColor); + } else { + setLineColor(newColor); + } + setUsesDiagramLineColor(false); umlDoc()->setModified(true); } break; case ListPopupMenu::mt_Fill_Color: - widget = umlScene()->getFirstMultiSelectedWidget(); - if (widget) { -//:TODO: newColour = widget->brush().color(); - newColour = widget->fillColor(); - } - if (KColorDialog::getColor(newColour)) { - umlScene()->selectionSetFillColor(newColour); + case ListPopupMenu::mt_Fill_Color_Selection: + newColor = fillColor(); + if (KColorDialog::getColor(newColor)) { + if (sel == ListPopupMenu::mt_Fill_Color_Selection) { + umlScene()->selectionSetFillColor(newColor); + } else { + setFillColor(newColor); + } umlDoc()->setModified(true); } break; case ListPopupMenu::mt_Use_Fill_Color: - umlScene()->selectionUseFillColor(!m_useFillColor); + setUseFillColor(!m_useFillColor); + break; + + case ListPopupMenu::mt_Set_Use_Fill_Color_Selection: + umlScene()->selectionUseFillColor(true); + break; + + case ListPopupMenu::mt_Unset_Use_Fill_Color_Selection: + umlScene()->selectionUseFillColor(false); break; case ListPopupMenu::mt_Show_Attributes_Selection: + case ListPopupMenu::mt_Hide_Attributes_Selection: + umlScene()->selectionSetVisualProperty( + ClassifierWidget::ShowAttributes, sel != ListPopupMenu::mt_Hide_Attributes_Selection + ); + break; + case ListPopupMenu::mt_Show_Operations_Selection: - case ListPopupMenu::mt_Visibility_Selection: - case ListPopupMenu::mt_DrawAsCircle_Selection: + case ListPopupMenu::mt_Hide_Operations_Selection: + umlScene()->selectionSetVisualProperty( + ClassifierWidget::ShowOperations, sel != ListPopupMenu::mt_Hide_Operations_Selection + ); + break; + + case ListPopupMenu::mt_Show_Visibility_Selection: + case ListPopupMenu::mt_Hide_Visibility_Selection: + umlScene()->selectionSetVisualProperty( + ClassifierWidget::ShowVisibility, sel != ListPopupMenu::mt_Hide_Visibility_Selection + ); + break; + case ListPopupMenu::mt_Show_Operation_Signature_Selection: + case ListPopupMenu::mt_Hide_Operation_Signature_Selection: + umlScene()->selectionSetVisualProperty( + ClassifierWidget::ShowOperationSignature, sel != ListPopupMenu::mt_Hide_Operation_Signature_Selection + ); + break; + case ListPopupMenu::mt_Show_Attribute_Signature_Selection: + case ListPopupMenu::mt_Hide_Attribute_Signature_Selection: + umlScene()->selectionSetVisualProperty( + ClassifierWidget::ShowAttributeSignature, sel != ListPopupMenu::mt_Hide_Attribute_Signature_Selection + ); + break; + case ListPopupMenu::mt_Show_Packages_Selection: + case ListPopupMenu::mt_Hide_Packages_Selection: + umlScene()->selectionSetVisualProperty( + ClassifierWidget::ShowPackage, sel != ListPopupMenu::mt_Hide_Packages_Selection + ); + break; + case ListPopupMenu::mt_Show_Stereotypes_Selection: - case ListPopupMenu::mt_Show_Public_Only_Selection: - umlScene()->selectionToggleShow(sel); - umlDoc()->setModified(true); + case ListPopupMenu::mt_Hide_Stereotypes_Selection: + umlScene()->selectionSetVisualProperty( + ClassifierWidget::ShowStereotype, sel != ListPopupMenu::mt_Hide_Stereotypes_Selection + ); + break; + + case ListPopupMenu::mt_Hide_NonPublic_Selection: + case ListPopupMenu::mt_Show_NonPublic_Selection: + umlScene()->selectionSetVisualProperty( + ClassifierWidget::ShowPublicOnly, sel != ListPopupMenu::mt_Show_NonPublic_Selection + ); break; + case ListPopupMenu::mt_ViewCode: { UMLClassifier *c = dynamic_cast(umlObject()); if (c) { @@ -806,7 +860,7 @@ break; } - case ListPopupMenu::mt_Delete_Selection: + case ListPopupMenu::mt_Delete: umlScene()->deleteSelection(); break; @@ -814,8 +868,11 @@ case ListPopupMenu::mt_Change_Font_Selection: { QFont newFont = font(); if (KFontDialog::getFont(newFont, KFontChooser::NoDisplayFlags, 0) == KFontDialog::Accepted) { - setFont(newFont); - //UMLApp::app()->executeCommand(new CmdChangeFontSelection(m_doc, m_pView, font)); + if (sel == ListPopupMenu::mt_Change_Font_Selection) { + m_scene->selectionSetFont(newFont); + } else { + setFont(newFont); + } } } break; @@ -841,10 +898,13 @@ break; case ListPopupMenu::mt_Clone: - // In principle we clone all the uml objects. { - UMLObject *pClone = umlObject()->clone(); - umlScene()->addObject(pClone); + foreach (UMLWidget* widget, umlScene()->selectedWidgets()) { + if (Model_Utils::isCloneable(widget->baseType())) { + UMLObject *clone = widget->umlObject()->clone(); + umlScene()->addObject(clone); + } + } } break; @@ -857,7 +917,30 @@ ft->handleRename(); break; } - + case ListPopupMenu::mt_Align_Right: + umlScene()->alignRight(); + break; + case ListPopupMenu::mt_Align_Left: + umlScene()->alignLeft(); + break; + case ListPopupMenu::mt_Align_Top: + umlScene()->alignTop(); + break; + case ListPopupMenu::mt_Align_Bottom: + umlScene()->alignBottom(); + break; + case ListPopupMenu::mt_Align_VerticalMiddle: + umlScene()->alignVerticalMiddle(); + break; + case ListPopupMenu::mt_Align_HorizontalMiddle: + umlScene()->alignHorizontalMiddle(); + break; + case ListPopupMenu::mt_Align_VerticalDistribute: + umlScene()->alignVerticalDistribute(); + break; + case ListPopupMenu::mt_Align_HorizontalDistribute: + umlScene()->alignHorizontalDistribute(); + break; default: uDebug() << "MenuType " << ListPopupMenu::toString(sel) << " not implemented"; break; diff -Nru umbrello-4.12.3/umbrello/widgets/widgetbase.h umbrello-4.12.90/umbrello/widgets/widgetbase.h --- umbrello-4.12.3/umbrello/widgets/widgetbase.h 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/widgets/widgetbase.h 2014-03-05 15:04:09.000000000 +0000 @@ -85,6 +85,8 @@ WidgetType baseType() const; QLatin1String baseTypeStr() const; + virtual void setSelected(bool select); + UMLScene* umlScene() const; UMLDoc* umlDoc() const; @@ -114,7 +116,7 @@ void setUsesDiagramLineWidth(bool state); bool useFillColor(); - void setUseFillColor(bool state); + virtual void setUseFillColor(bool state); bool usesDiagramTextColor() const; void setUsesDiagramTextColor(bool state); @@ -148,7 +150,6 @@ protected: virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent *event); - virtual void setupContextMenuActions(ListPopupMenu &menu); WidgetType m_baseType; ///< Type of widget. UMLScene *m_scene; diff -Nru umbrello-4.12.3/umbrello/widgets/widget_factory.cpp umbrello-4.12.90/umbrello/widgets/widget_factory.cpp --- umbrello-4.12.3/umbrello/widgets/widget_factory.cpp 2014-02-27 09:01:49.000000000 +0000 +++ umbrello-4.12.90/umbrello/widgets/widget_factory.cpp 2014-03-05 15:04:09.000000000 +0000 @@ -12,52 +12,51 @@ #include "widget_factory.h" // app includes -#include "debug_utils.h" -#include "uml.h" -#include "umldoc.h" -#include "umlview.h" -#include "object_factory.h" -#include "floatingtextwidget.h" -#include "classifierwidget.h" +#include "activitywidget.h" +#include "actor.h" +#include "actorwidget.h" +#include "artifact.h" +#include "artifactwidget.h" +#include "associationwidget.h" +#include "boxwidget.h" +#include "category.h" +#include "categorywidget.h" #include "classifier.h" -#include "packagewidget.h" -#include "package.h" -#include "folder.h" -#include "componentwidget.h" +#include "classifierwidget.h" +#include "cmds.h" +#include "combinedfragmentwidget.h" #include "component.h" -#include "nodewidget.h" -#include "node.h" -#include "artifactwidget.h" -#include "artifact.h" +#include "componentwidget.h" #include "datatypewidget.h" -#include "enumwidget.h" -#include "enum.h" -#include "entitywidget.h" +#include "debug_utils.h" #include "entity.h" -#include "regionwidget.h" -#include "actorwidget.h" -#include "actor.h" -#include "usecasewidget.h" -#include "usecase.h" -#include "notewidget.h" -#include "boxwidget.h" -#include "category.h" -#include "associationwidget.h" +#include "entitywidget.h" +#include "enum.h" +#include "enumwidget.h" +#include "floatingdashlinewidget.h" +#include "floatingtextwidget.h" +#include "folder.h" +#include "forkjoinwidget.h" #include "messagewidget.h" +#include "node.h" +#include "nodewidget.h" +#include "notewidget.h" +#include "object_factory.h" +#include "objectnodewidget.h" #include "objectwidget.h" -#include "statewidget.h" -#include "forkjoinwidget.h" -#include "activitywidget.h" -#include "combinedfragmentwidget.h" -#include "seqlinewidget.h" +#include "package.h" +#include "packagewidget.h" +#include "pinwidget.h" #include "preconditionwidget.h" +#include "regionwidget.h" #include "signalwidget.h" -#include "floatingdashlinewidget.h" -#include "objectnodewidget.h" -#include "pinwidget.h" -#include "categorywidget.h" -#include "cmds.h" +#include "statewidget.h" +#include "uml.h" +#include "umldoc.h" #include "umlscene.h" +#include "umlview.h" +#include "usecase.h" +#include "usecasewidget.h" namespace Widget_Factory { @@ -74,7 +73,7 @@ switch (type) { case UMLObject::ot_Actor: if (diagramType == Uml::DiagramType::Sequence) { - ObjectWidget *ow = new ObjectWidget(scene, o, scene->localID()); + ObjectWidget *ow = new ObjectWidget(scene, o); ow->setDrawAsActor(true); y = ow->topMargin(); newWidget = ow; @@ -110,7 +109,7 @@ break; case UMLObject::ot_Interface: if (diagramType == Uml::DiagramType::Sequence || diagramType == Uml::DiagramType::Collaboration) { - ObjectWidget *ow = new ObjectWidget(scene, o, scene->localID()); + ObjectWidget *ow = new ObjectWidget(scene, o); if (diagramType == Uml::DiagramType::Sequence) { y = ow->topMargin(); } @@ -133,7 +132,7 @@ cw->setDrawAsCircle(true); newWidget = cw; } else { - ObjectWidget *ow = new ObjectWidget(scene, o, scene->localID()); + ObjectWidget *ow = new ObjectWidget(scene, o); if (diagramType == Uml::DiagramType::Sequence) { y = ow->topMargin(); }