void CppTree2Uml::parseDeclaration2(GroupAST* funSpec, GroupAST* storageSpec, TypeSpecifierAST* typeSpec, InitDeclaratorAST* decl) { if (m_inStorageSpec) return; DeclaratorAST* d = decl->declarator(); if (!d) return; if (!d->subDeclarator() && d->parameterDeclarationClause()) return parseFunctionDeclaration(funSpec, storageSpec, typeSpec, decl); DeclaratorAST* t = d; while (t && t->subDeclarator()) t = t->subDeclarator(); QString id; if (t && t->declaratorId() && t->declaratorId()->unqualifiedName()) id = t->declaratorId()->unqualifiedName()->text(); if (!scopeOfDeclarator(d, QStringList()).isEmpty()){ uDebug() << id << ": skipping."; return; } UMLClassifier *c = m_currentClass[m_clsCnt]; if (c == NULL) { uDebug() << id << ": need a surrounding class."; return; } QString typeName = typeOfDeclaration(typeSpec, d); //:unused: bool isFriend = false; bool isStatic = false; //:unused: bool isInitialized = decl->initializer() != 0; if (storageSpec){ QList<AST*> l = storageSpec->nodeList(); for (int i = 0; i < l.size(); ++i) { QString text = l.at(i)->text(); if (text == QLatin1String("static")) isStatic = true; //:unused: else if (text == QLatin1String("friend")) isFriend = true; } } Import_Utils::insertAttribute(c, m_currentAccess, id, typeName, m_comment, isStatic); m_comment = QString(); }
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("<unnamed>") : s; scope.push_back( s ); } break; case NodeType_Namespace: { AST* namespaceName = ((NamespaceAST*)ast)->namespaceName(); s = namespaceName ? namespaceName->text() : QString::fromLatin1("<unnamed>"); scope.push_back( s ); } break; case NodeType_FunctionDefinition: { FunctionDefinitionAST* funDef = static_cast<FunctionDefinitionAST*>( ast ); DeclaratorAST* d = funDef->initDeclarator()->declarator(); // hotfix for bug #68726 if ( !d->declaratorId() ) break; QList<ClassOrNamespaceNameAST*> 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; } }
void CppTree2Uml::parseFunctionDeclaration(GroupAST* funSpec, GroupAST* storageSpec, TypeSpecifierAST * typeSpec, InitDeclaratorAST * decl) { bool isFriend = false; //:unused: bool isVirtual = false; bool isStatic = false; //:unused: bool isInline = false; bool isPure = decl->initializer() != 0; bool isConstructor = false; if (funSpec){ //:unused: QList<AST*> l = funSpec->nodeList(); //:unused: for (int i = 0; i < l.size(); ++i) { //:unused: QString text = l.at(i)->text(); //:unused: if (text == QLatin1String("virtual")) isVirtual = true; //:unused: else if (text == QLatin1String("inline")) isInline = true; //:unused: } } if (storageSpec){ QList<AST*> l = storageSpec->nodeList(); for (int i = 0; i < l.size(); ++i) { QString text = l.at(i)->text(); if (text == QLatin1String("friend")) isFriend = true; else if (text == QLatin1String("static")) isStatic = true; } } DeclaratorAST* d = decl->declarator(); QString id = d->declaratorId()->unqualifiedName()->text(); UMLClassifier *c = m_currentClass[m_clsCnt]; if (c == NULL) { uDebug() << id << ": need a surrounding class."; return; } QString returnType = typeOfDeclaration(typeSpec, d); UMLOperation *m = Import_Utils::makeOperation(c, id); // if a class has no return type, it could de a constructor or // a destructor if (d && returnType.isEmpty() && id.indexOf(QLatin1Char('~')) == -1) isConstructor = true; parseFunctionArguments(d, m); Import_Utils::insertMethod(c, m, m_currentAccess, returnType, isStatic, isPure, isFriend, isConstructor, m_comment); m_comment = QString(); }
void CppTree2Uml::parseTemplateDeclaration(TemplateDeclarationAST* ast) { TemplateParameterListAST* parmListAST = ast->templateParameterList(); if (parmListAST == NULL) return; QList<TemplateParameterAST*> parmList = parmListAST->templateParameterList(); for (int i = 0; i < parmList.size(); ++i) { // The template is either a typeParameter or a typeValueParameter. TemplateParameterAST* tmplParmNode = parmList.at(i); TypeParameterAST* typeParmNode = tmplParmNode->typeParameter(); if (typeParmNode) { NameAST* nameNode = typeParmNode->name(); if (nameNode) { QString typeName = nameNode->unqualifiedName()->text(); Model_Utils::NameAndType nt(typeName, NULL); m_templateParams.append(nt); } else { uError() << "nameNode is NULL"; } } ParameterDeclarationAST* valueNode = tmplParmNode->typeValueParameter(); if (valueNode) { TypeSpecifierAST* typeSpec = valueNode->typeSpec(); if (typeSpec == NULL) { uError() << "typeSpec is NULL"; continue; } QString typeName = typeSpec->name()->text(); UMLObject *t = Import_Utils::createUMLObject(UMLObject::ot_UMLObject, typeName, m_currentNamespace[m_nsCnt]); DeclaratorAST* declNode = valueNode->declarator(); NameAST* nameNode = declNode->declaratorId(); if (nameNode == NULL) { uError() << "CppTree2Uml::parseTemplateDeclaration(value):" << " nameNode is NULL"; continue; } QString paramName = nameNode->unqualifiedName()->text(); Model_Utils::NameAndType nt(paramName, t); m_templateParams.append(nt); } } if (ast->declaration()) TreeParser::parseDeclaration(ast->declaration()); }
void CppTree2Uml::parseFunctionDefinition(FunctionDefinitionAST* ast) { TypeSpecifierAST* typeSpec = ast->typeSpec(); GroupAST* funSpec = ast->functionSpecifier(); GroupAST* storageSpec = ast->storageSpecifier(); if (!ast->initDeclarator()) return; DeclaratorAST* d = ast->initDeclarator()->declarator(); if (!d->declaratorId()) return; bool isFriend = false; //:unused: bool isVirtual = false; bool isStatic = false; //:unused: bool isInline = false; bool isConstructor = false; if (funSpec){ //:unused: QList<AST*> l = funSpec->nodeList(); //:unused: for (int i = 0; i < l.size(); ++i) { //:unused: QString text = l.at(i)->text(); //:unused: if (text == "virtual") isVirtual = true; //:unused: else if (text == "inline") isInline = true; //:unused: } } if (storageSpec){ QList<AST*> l = storageSpec->nodeList(); for (int i = 0; i < l.size(); ++i) { QString text = l.at(i)->text(); if (text == QLatin1String("friend")) isFriend = true; else if (text == QLatin1String("static")) isStatic = true; } } QString id = d->declaratorId()->unqualifiedName()->text().trimmed(); if (m_thread) { m_thread->emitMessageToLog(QString(), QLatin1String("method ") + id); } uDebug() << id; UMLClassifier *c = m_currentClass[m_clsCnt]; if (c == NULL) { uDebug() << id << ": need a surrounding class."; return; } QString returnType = typeOfDeclaration(typeSpec, d); UMLOperation *m = Import_Utils::makeOperation(c, id); // if a class has no return type, it could be a constructor or // a destructor if (d && returnType.isEmpty() && id.indexOf(QLatin1Char('~')) == -1) isConstructor = true; parseFunctionArguments(d, m); Import_Utils::insertMethod(c, m, m_currentAccess, returnType, isStatic, false /*isAbstract*/, isFriend, isConstructor, m_comment); m_comment = QString(); /* For reference, Kdevelop does some more: method->setFileName(m_fileName); if (m_inSignals) method->setSignal(true); if (m_inSlots) method->setSlot(true); */ }
void CppTree2Uml::parseTypedef(TypedefAST* ast) { TypeSpecifierAST* typeSpec = ast->typeSpec(); InitDeclaratorListAST* declarators = ast->initDeclaratorList(); if (typeSpec && declarators){ QString typeId; if (typeSpec->name()) typeId = typeSpec->name()->text(); QList<InitDeclaratorAST*> l(declarators->initDeclaratorList()); InitDeclaratorAST* initDecl = 0; for (int i = 0; i < l.size(); ++i) { initDecl = l.at(i); if (initDecl==0) break; QString type, id; if (initDecl->declarator()){ type = typeOfDeclaration(typeSpec, initDecl->declarator()); DeclaratorAST* d = initDecl->declarator(); while (d->subDeclarator()){ d = d->subDeclarator(); } if (d->declaratorId()) id = d->declaratorId()->text(); } /* @todo Trace typedefs back to their root type for deciding whether to build a Datatype (for pointers.) */ /* check out if the ID type is a Datatype ex: typedef unsigned int uint; where unsigned int is a known datatype I'm not sure if setIsReference() should be run */ bool isDatatype = Import_Utils::isDatatype(typeId, m_currentNamespace[m_nsCnt]); if (type.contains(QLatin1Char('*')) || isDatatype) { UMLObject *inner = 0; if (m_currentNamespace[m_nsCnt] && m_currentNamespace[m_nsCnt]->baseType() == UMLObject::ot_Class && typeId == m_currentNamespace[m_nsCnt]->name()) inner = m_currentNamespace[m_nsCnt]; else inner = Import_Utils::createUMLObject(UMLObject::ot_Class, typeId, m_currentNamespace[m_nsCnt]); UMLObject *typedefObj = Import_Utils::createUMLObject(UMLObject::ot_Datatype, id, m_currentNamespace[m_nsCnt]); UMLClassifier *dt = static_cast<UMLClassifier*>(typedefObj); dt->setIsReference(); dt->setOriginType(static_cast<UMLClassifier*>(inner)); } else { Import_Utils::createUMLObject(UMLObject::ot_Class, id, m_currentNamespace[m_nsCnt], QString() /* doc */, QLatin1String("typedef") /* stereotype */); } } } }