// not from a form 'generic<...C...> var' where C is a class bool UmlRelation::new_one(Class * container, const WrapperStr & name, UmlTypeSpec & dest, WrapperStr str_actuals, aVisibility visibility, bool staticp, bool constp, bool transientp, bool volatilep, const WrapperStr & array, const WrapperStr & value, WrapperStr comment, WrapperStr description, WrapperStr annotation #ifdef ROUNDTRIP , bool roundtrip, QList<UmlItem *> & expected_order #endif ) { #ifdef TRACE QLOG_INFO() << "RELATION '" << name << "' from '" << cl->Name() << "' to '" << dest.type->Name() << "' array '" << array << "'\n"; #endif if ( #ifdef REVERSE container->from_libp() && #endif (visibility == PrivateVisibility)) { Lex::finish_line(); Lex::clear_comments(); return TRUE; } UmlClass * cl = container->get_uml(); UmlRelation * rel; #ifdef ROUNDTRIP bool created; if (!roundtrip || ((rel = search_rel(container, name, dest.type, "")) == 0)) { #endif rel = UmlBaseRelation::create(aDirectionalAssociation, cl, dest.type); if (rel == 0) { JavaCatWindow::trace(WrapperStr("<font face=helvetica><b>cannot add relation <i>") + name + "</i> in <i>" + cl->name() + "</i> to <i>" + dest.type->name() + "</i></b></font><br>"); return FALSE; } #ifdef REVERSE # ifndef ROUNDTRIP Statistic::one_relation_more(); # else if (roundtrip) container->set_updated(); created = TRUE; } else created = FALSE; # endif #endif WrapperStr decl = JavaSettings::relationDecl(array); UmlClass::manage_generic(decl, dest, str_actuals, "${type}"); Lex::finish_line(); comment = Lex::get_comments(comment); description = Lex::get_description(description); #ifdef ROUNDTRIP if (roundtrip && !created) { if (rel->visibility() != visibility) { rel->set_Visibility(visibility); container->set_updated(); } if (decl.find("${description}") != -1) { if (nequal(rel->description(), description)) { rel->set_Description(description); container->set_updated(); } } else if (nequal(rel->description(), Lex::simplify_comment(comment))) { rel->set_Description(comment); // comment was set container->set_updated(); } if (rel->isReadOnly() != constp) { rel->set_isReadOnly(constp); container->set_updated(); } if (rel->isJavaTransient() != transientp) { rel->set_isJavaTransient(transientp); container->set_updated(); } if (rel->isVolatile() != volatilep) { rel->set_isVolatile(volatilep); container->set_updated(); } if (rel->isClassMember() != staticp) { rel->set_isClassMember(staticp); container->set_updated(); } if (neq(rel->multiplicity(), array)) { rel->set_Multiplicity(array); container->set_updated(); } WrapperStr v = rel->defaultValue(); if (!v.isEmpty() && (((const char *) v)[0] == '=')) v = v.mid(1); if (nequal(v, value)) { rel->set_DefaultValue(value); container->set_updated(); } if (nequal(rel->javaAnnotations(), annotation)) { rel->set_JavaAnnotations(annotation); container->set_updated(); } if (neq(rel->javaDecl(), decl)) { rel->set_JavaDecl(decl); container->set_updated(); } rel->set_usefull(); expected_order.append(rel); } else { #endif rel->set_Visibility(visibility); if (!comment.isEmpty()) rel->set_Description((decl.find("${description}") != -1) ? description : comment); if (constp) rel->set_isReadOnly(TRUE); if (transientp) rel->set_isJavaTransient(TRUE); if (volatilep) rel->set_isVolatile(TRUE); if (staticp) rel->set_isClassMember(TRUE); if (!array.isEmpty()) rel->set_Multiplicity(array); if (! value.isEmpty()) rel->set_DefaultValue(value); if (! annotation.isEmpty()) rel->set_JavaAnnotations(annotation); rel->set_JavaDecl(decl); rel->set_RoleName(name); #ifdef ROUNDTRIP if (roundtrip) expected_order.append(rel); } #endif return TRUE; }
bool UmlRelation::new_one(Class * container, const Q3CString & name, UmlClass * dest, const Q3CString & modifier, const Q3CString & pretype, const Q3CString & array, const Q3CString & typeform, aVisibility visibility, bool staticp, bool constp, bool mutablep, bool volatilep, const Q3CString & value, Q3CString comment, Q3CString description #ifdef ROUNDTRIP , bool roundtrip, Q3PtrList<UmlItem> & expected_order #endif ) { #ifdef DEBUG_BOUML cout << "RELATION '" << name << "' from '" << cl->name() << "' to '" << dest->name() << "' modifier '" << modifier << "' array '" << array << "' typeform '" << typeform << "'\n"; #endif if ( #ifdef REVERSE container->from_libp() && #endif (visibility == PrivateVisibility)) { Lex::finish_line(); Lex::clear_comments(); return TRUE; } UmlClass * cl = container->get_uml(); UmlRelation * rel; #ifdef ROUNDTRIP if (roundtrip && ((rel = search_rel(container, name, dest, "")) != 0)) { rel->set_usefull(); expected_order.append(rel); } else { #endif rel = UmlBaseRelation::create((modifier.isEmpty() && ((typeform == "${type}") || (typeform[typeform.find("${type}") + 7] != '*'))) ? aDirectionalAggregationByValue : aDirectionalAssociation, cl, dest); if (rel == 0) { UmlCom::trace(Q3CString("<font face=helvetica><b>cannot add relation <i>") + name + "</i> in <i>" + cl->name() + "</i> to <i>" + dest->name() + "</i></b></font><br><hr>"); return FALSE; } #ifdef REVERSE # ifndef ROUNDTRIP Statistic::one_relation_more(); # else if (roundtrip) { expected_order.append(rel); container->set_updated(); roundtrip = FALSE; } } # endif #endif Lex::finish_line(); comment = Lex::get_comments(comment); description = Lex::get_description(description); #ifdef ROUNDTRIP if (roundtrip) { if (rel->visibility() != visibility) { rel->set_Visibility(visibility); container->set_updated(); } if (rel->isReadOnly() != constp) { rel->set_isReadOnly(constp); container->set_updated(); } if (rel->isClassMember() != staticp) { rel->set_isClassMember(staticp); container->set_updated(); } if (rel->isCppMutable() != mutablep) { rel->set_isCppMutable(mutablep); container->set_updated(); } if (rel->isVolatile() != volatilep) { rel->set_isVolatile(volatilep); container->set_updated(); } } else { #endif rel->set_Visibility(visibility); if (constp) rel->set_isReadOnly(TRUE); if (staticp) rel->set_isClassMember(TRUE); if (mutablep) rel->set_isCppMutable(TRUE); if (volatilep) rel->set_isVolatile(TRUE); #ifdef ROUNDTRIP } #endif Q3CString decl; if (typeform != "${type}") { // array & modified are empty, pretype is empty ? decl = CppSettings::relationDecl(TRUE, "*"); int index = typeform.find("<"); // cannot be -1 Q3CString st = typeform.left(index); Q3CString st_uml = CppSettings::umlType(st); #ifdef ROUNDTRIP if (roundtrip) { if (st_uml.isEmpty()) st_uml = st; if (neq(rel->stereotype(), st_uml)) { rel->set_Stereotype(st_uml); container->set_updated(); } } else #endif rel->set_Stereotype((st_uml.isEmpty()) ? st : st_uml); int index2; if ((index2 = decl.find("<${type}>")) == -1) { decl = " ${comment}${static}${mutable}${volatile}${const}${stereotype}<${type}> ${name}${value};"; index2 = decl.find("<${type}>"); } decl.replace(index2, 9, typeform.mid(index)); } else { if (!array.isEmpty()) { #ifdef ROUNDTRIP if (roundtrip) { if (neq(rel->multiplicity(), array)) { rel->set_Multiplicity(array); container->set_updated(); } } else #endif rel->set_Multiplicity(array); } decl = CppSettings::relationDecl(modifier != "*", array); int index; if (!pretype.isEmpty() && ((index = decl.find("${type}")) != 0)) decl.insert(index,(const char*)( pretype + " ")); if ((modifier == "&") && ((index = decl.find("${type}")) != 0)) decl.insert(index + 7, " &"); } if (! value.isEmpty()) { int index = decl.find("${value}"); if (index != -1) decl.insert(index + 2, "h_"); #ifdef ROUNDTRIP if (roundtrip) { if (!staticp) { Q3CString v = rel->defaultValue(); if (!v.isEmpty() && (((const char *) v)[0] == '=')) v = v.mid(1); if (nequal(v, value)) { rel->set_DefaultValue(value); container->set_updated(); } } } else #endif rel->set_DefaultValue(value); } #ifdef ROUNDTRIP if (roundtrip) { if (neq(rel->cppDecl(), decl)) { rel->set_CppDecl(decl); container->set_updated(); } if (decl.find("${description}") != -1) { if (nequal(rel->description(), description)) { rel->set_Description(description); container->set_updated(); } } else if (nequal(rel->description(), Lex::simplify_comment(comment))) { rel->set_Description(comment); // comment was set container->set_updated(); } // role name is the right one return TRUE; } #endif rel->set_CppDecl(decl); if (!comment.isEmpty()) rel->set_Description((decl.find("${description") != -1) ? description : Lex::simplify_comment(comment)); return rel->set_RoleName(name); }
// from a form 'generic<...C...> var' where C is a class bool UmlRelation::new_one(Class * container, const QCString & name, UmlClass * type, QCString type_def, QCString genericname, aVisibility visibility, bool staticp, bool constp, bool transientp, bool volatilep, const QCString & array, const QCString & value, QCString comment, QCString description, QCString annotation #ifdef ROUNDTRIP , bool roundtrip, QList<UmlItem> & expected_order #endif ) { #ifdef TRACE cout << "RELATION '" << name << "' from '" << cl->Name() << "' to '" << type->Name() << "' array '" << array << "'\n"; #endif if ( #ifdef REVERSE container->from_libp() && #endif (visibility == PrivateVisibility)) { Lex::finish_line(); Lex::clear_comments(); return TRUE; } QCString st = JavaSettings::umlType(genericname); if (st.isEmpty()) st = genericname; UmlClass * cl = container->get_uml(); UmlRelation * rel; #ifdef ROUNDTRIP bool created; if (!roundtrip || ((rel = search_rel(container, name, type, st)) == 0)) { #endif rel = UmlBaseRelation::create(aDirectionalAssociation, cl, type); if (rel == 0) { JavaCatWindow::trace(QCString("<font face=helvetica><b>cannot add relation <i>") + name + "</i> in <i>" + cl->name() + "</i> to <i>" + type->name() + "</i></b></font><br>"); return FALSE; } #ifdef REVERSE # ifndef ROUNDTRIP Statistic::one_relation_more(); # else if (roundtrip) container->set_updated(); created = TRUE; } else created = FALSE; # endif #endif Lex::finish_line(); comment = Lex::get_comments(comment); description = Lex::get_description(description); QCString decl = JavaSettings::relationDecl(array); type_def.replace(0, genericname.length(), "${stereotype}"); decl.replace(decl.find("${type}"), 7, type_def); #ifdef ROUNDTRIP if (roundtrip && !created) { if (rel->visibility() != visibility) { rel->set_Visibility(visibility); container->set_updated(); } if (decl.find("${description}") != -1) { if (nequal(rel->description(), description)) { rel->set_Description(description); container->set_updated(); } } else if (nequal(rel->description(), Lex::simplify_comment(comment))) { rel->set_Description(comment); // comment was set container->set_updated(); } if (rel->isReadOnly() != constp) { rel->set_isReadOnly(constp); container->set_updated(); } if (rel->isJavaTransient() != transientp) { rel->set_isJavaTransient(transientp); container->set_updated(); } if (rel->isVolatile() != volatilep) { rel->set_isVolatile(volatilep); container->set_updated(); } if (rel->isClassMember() != staticp) { rel->set_isClassMember(staticp); container->set_updated(); } if (neq(rel->multiplicity(), array)) { rel->set_Multiplicity(array); container->set_updated(); } if (neq(rel->defaultValue(), value)) { rel->set_DefaultValue(value); container->set_updated(); } if (nequal(rel->javaAnnotations(), annotation)) { rel->set_JavaAnnotations(annotation); container->set_updated(); } if (neq(rel->stereotype(), st) && (rel->stereotype().isEmpty() || (JavaSettings::relationAttributeStereotype(rel->stereotype()) != st))) { rel->set_Stereotype(st); container->set_updated(); } if (neq(rel->javaDecl(), decl)) { rel->set_JavaDecl(decl); container->set_updated(); } // role name is the right one rel->set_usefull(); expected_order.append(rel); } else { #endif rel->set_Visibility(visibility); if (!comment.isEmpty()) rel->set_Description((decl.find("${description}") != -1) ? description : Lex::simplify_comment(comment)); if (constp) rel->set_isReadOnly(TRUE); if (transientp) rel->set_isJavaTransient(TRUE); if (volatilep) rel->set_isVolatile(TRUE); if (staticp) rel->set_isClassMember(TRUE); if (!array.isEmpty()) rel->set_Multiplicity(array); if (! value.isEmpty()) rel->set_DefaultValue(value); if (! annotation.isEmpty()) rel->set_JavaAnnotations(annotation); rel->set_Stereotype(st); rel->set_JavaDecl(decl); rel->set_RoleName(name); #ifdef ROUNDTRIP if (roundtrip) expected_order.append(rel); } #endif return TRUE; }
void UmlClass::gen_cpp_decl(QCString s, bool descr) { const char * p = (descr) ? (const char *) s : (const char *) bypass_comment(s); while (*p) { if (!strncmp(p, "${comment}", 10)) p += 10; else if (!strncmp(p, "${description}", 14)) p += 14; else if (!strncmp(p, "${type}", 7)) { p += 7; bool find = FALSE; if (baseType().type != 0) { UmlClass * mother = baseType().type; const QVector<UmlItem> ch = children(); for (unsigned i = 0; i != ch.size(); i += 1) { if (ch[i]->kind() == aRelation) { UmlRelation * rel = (UmlRelation *) ch[i]; aRelationKind k = rel->relationKind(); if (((k == aGeneralisation) || (k == aRealization)) && (rel->roleType() == mother)) { rel->roleType()->write(); generate(actuals(), mother, TRUE); find = TRUE; break; } } } } if (! find) UmlItem::write(baseType(), cppLanguage); } else if (!strncmp(p, "${template}", 11)) { p += 11; generate(formals()); } else if (!strncmp(p, "${name}", 7)) { p += 7; writeq(name()); } else if (!strncmp(p, "${inherit}", 10)) { p += 10; const QVector<UmlItem> ch = children(); const char * sep = " : "; for (unsigned i = 0; i != ch.size(); i += 1) { if (ch[i]->kind() == aRelation) { UmlRelation * rel = (UmlRelation *) ch[i]; aRelationKind k = rel->relationKind(); if (((k == aGeneralisation) || (k == aRealization)) && !rel->cppDecl().isEmpty()) { fw.write(sep); // UmlItem::write else G++ call UmlClass::write(QCString) ! UmlItem::write((rel->cppVisibility() == DefaultVisibility) ? rel->visibility() : rel->cppVisibility(), cppLanguage); fw.write((rel->cppVirtualInheritance()) ? " virtual " : " "); rel->roleType()->write(); generate(actuals(), rel->roleType(), TRUE); sep = ", "; } } } } else if (*p == '{') { if (descr) fw.write(*p++); else break; } else if (*p == '\r') p += 1; else if (*p == '\n') { if (descr) { fw.write("<br />"); p += 1; } else { fw.write(' '); do p += 1; while ((*p != 0) && (*p <= ' ')); } } else if (*p == '@') manage_alias(p); else writeq(*p++); } }
bool UmlClass::manage_inherit(ClassContainer * container, const QList<FormalParameterList> & tmplts #ifdef REVERSE , bool libp # ifdef ROUNDTRIP , bool roundtrip, QList<UmlItem *> & expected_order , bool container_roundtrip, QList<UmlItem *> & container_expected_order # endif #endif ) { #ifdef DEBUG_DOUML QLOG_INFO() << name() << "->manage_inherit()\n"; #endif WrapperStr s = Lex::read_word(TRUE); while (s != "{") { #ifdef DEBUG_DOUML QLOG_INFO() << "Class::manage_inherit, visibility : " << s << '\n'; #endif bool is_virtual; if (s == "virtual") { is_virtual = TRUE; s = Lex::read_word(TRUE); } else is_virtual = FALSE; aVisibility v; if (s == "public") { v = PublicVisibility; s = Lex::read_word(TRUE); } else if (s == "protected") { v = ProtectedVisibility; s = Lex::read_word(TRUE); } else if (s == "private") { v = PrivateVisibility; s = Lex::read_word(TRUE); } else v = PrivateVisibility; if (s.isEmpty()) { Lex::premature_eof(); return FALSE; } #ifdef DEBUG_DOUML QLOG_INFO() << "UmlClass::manage_inherit, mother : " << s << '\n'; #endif WrapperStr mother_name = s; UmlTypeSpec mother; WrapperStr typeform; UmlRelation * rel = 0; #ifdef ROUNDTRIP bool is_new = TRUE; #endif container->compute_type(s, mother, typeform); s = Lex::read_word(); if (s == "<") { Lex::mark(); // goes up to the corresponding '>' WrapperStr after_gt; Lex::finish_template(after_gt); s = Lex::read_word(TRUE); if (*s == ':') { // inherits 'T<...>::...' // don't try to solve, use a typedef named 'Type_<n>' based on T<...>::... // creating this typedef if it doesn't yet exist mother_name += "<" + Lex::region(); mother.type = 0; // made below s = Lex::read_word(); } else if (mother.type == 0) { mother_name += "<" + after_gt; } else { // inherits T<...> #ifdef ROUNDTRIP is_new = !roundtrip || ((rel = search_for_inherit(mother.type)) == 0); #endif mother_name += "<" + after_gt; Lex::come_back(); // must add inheritance before setting actuals if ( #ifdef ROUNDTRIP is_new && ( #endif (rel = UmlBaseRelation::create(aRealization, this, mother.type)) == 0 #ifdef ROUNDTRIP ) #endif ) { Lex::warn("cannot inherit <font color =\"red\">" + Lex::quote(mother_name) + " </font>"); #ifdef DEBUG_DOUML QLOG_INFO() << "cannot create <|---\n"; #endif return FALSE; } else if (!get_actuals(mother.type, container, tmplts #ifdef ROUNDTRIP , !is_new #endif )) return FALSE; #ifdef ROUNDTRIP if (! is_new) { if (neq(rel->stereotype(), "bind")) { rel->set_Stereotype("bind"); the_class->set_updated(); } } else #endif rel->set_Stereotype("bind"); s = Lex::read_word(); } } if (mother.type == 0) { mother.type = auxilarily_typedef(mother_name #ifdef REVERSE , libp # ifdef ROUNDTRIP , container_roundtrip , container_expected_order # endif #endif ); if (mother.type == 0) return FALSE; } #ifdef ROUNDTRIP if (rel == 0) is_new = !roundtrip || ((rel = search_for_inherit(mother.type)) == 0); #endif if ((rel == 0) && ((rel = UmlBaseRelation::create(aGeneralisation, this, mother.type)) == 0)) { Lex::warn("cannot inherit <font color =\"red\">" + Lex::quote(mother_name) + " </font>"); #ifdef DEBUG_DOUML QLOG_INFO() << "cannot create <|---\n"; #endif return FALSE; } #ifdef ROUNDTRIP expected_order.append(rel); if (!is_new) { rel->set_usefull(); if (neq(rel->cppDecl(), "${type}")) { rel->set_CppDecl("${type}"); the_class->set_updated(); } if (rel->visibility() != v) { rel->set_Visibility(v); the_class->set_updated(); } if (is_virtual != rel->cppVirtualInheritance()) { rel->set_CppVirtualInheritance(is_virtual); the_class->set_updated(); } } else { #elif defined(REVERSE) Statistic::one_relation_more(); #endif rel->set_CppDecl("${type}"); rel->set_Visibility(v); if (is_virtual) rel->set_CppVirtualInheritance(TRUE); #ifdef ROUNDTRIP } #endif if (s == ",") s = Lex::read_word(); } Lex::unread_word(); // '{' return TRUE; }