From b61143a5b204c7d55a0317c8b90a8972286e766c Mon Sep 17 00:00:00 2001 From: Bartek Kryza Date: Sun, 28 Mar 2021 22:21:41 +0200 Subject: [PATCH] Ported template instantiation handling to cppast --- src/cx/util.h | 2 +- src/puml/class_diagram_generator.h | 50 +- src/puml/sequence_diagram_generator.h | 12 +- src/uml/class_diagram_model.cc | 46 +- src/uml/class_diagram_visitor.cc | 47 +- src/uml/sequence_diagram_visitor.h | 171 +++-- tests/catch.h | 925 +++++++++++++------------- tests/t00003/test_case.h | 3 +- tests/t00009/test_case.h | 3 +- tests/t00011/test_case.h | 2 +- tests/t00012/t00012.cc | 1 + tests/t00012/test_case.h | 2 +- 12 files changed, 642 insertions(+), 622 deletions(-) diff --git a/src/cx/util.h b/src/cx/util.h index 2602adfb..73071791 100644 --- a/src/cx/util.h +++ b/src/cx/util.h @@ -44,7 +44,7 @@ std::string full_name(const cppast::cpp_entity &e); std::string fully_prefixed(const cppast::cpp_entity &e); -const cppast::cpp_type& unreferenced(const cppast::cpp_type &t); +const cppast::cpp_type &unreferenced(const cppast::cpp_type &t); } // namespace util } // namespace cx diff --git a/src/puml/class_diagram_generator.h b/src/puml/class_diagram_generator.h index f5976fba..79a56f62 100644 --- a/src/puml/class_diagram_generator.h +++ b/src/puml/class_diagram_generator.h @@ -67,37 +67,37 @@ public: std::string to_string(scope_t scope) const { switch (scope) { - case scope_t::kPublic: - return "+"; - case scope_t::kProtected: - return "#"; - case scope_t::kPrivate: - return "-"; - default: - return ""; + case scope_t::kPublic: + return "+"; + case scope_t::kProtected: + return "#"; + case scope_t::kPrivate: + return "-"; + default: + return ""; } } std::string to_string(relationship_t r) const { switch (r) { - case relationship_t::kOwnership: - case relationship_t::kComposition: - return "*--"; - case relationship_t::kAggregation: - return "o--"; - case relationship_t::kContainment: - return "--+"; - case relationship_t::kAssociation: - return "-->"; - case relationship_t::kInstantiation: - return "..|>"; - case relationship_t::kFriendship: - return "<.."; - case relationship_t::kDependency: - return "..>"; - default: - return ""; + case relationship_t::kOwnership: + case relationship_t::kComposition: + return "*--"; + case relationship_t::kAggregation: + return "o--"; + case relationship_t::kContainment: + return "--+"; + case relationship_t::kAssociation: + return "-->"; + case relationship_t::kInstantiation: + return "..|>"; + case relationship_t::kFriendship: + return "<.."; + case relationship_t::kDependency: + return "..>"; + default: + return ""; } } diff --git a/src/puml/sequence_diagram_generator.h b/src/puml/sequence_diagram_generator.h index 2e7c233f..1d717d75 100644 --- a/src/puml/sequence_diagram_generator.h +++ b/src/puml/sequence_diagram_generator.h @@ -54,12 +54,12 @@ public: std::string to_string(message_t r) const { switch (r) { - case message_t::kCall: - return "->"; - case message_t::kReturn: - return "<--"; - default: - return ""; + case message_t::kCall: + return "->"; + case message_t::kReturn: + return "<--"; + default: + return ""; } } diff --git a/src/uml/class_diagram_model.cc b/src/uml/class_diagram_model.cc index 0d7ea761..63a37dfd 100644 --- a/src/uml/class_diagram_model.cc +++ b/src/uml/class_diagram_model.cc @@ -26,32 +26,30 @@ std::atomic_uint64_t element::m_nextId = 1; std::string to_string(relationship_t r) { switch (r) { - case relationship_t::kNone: - return "none"; - case relationship_t::kExtension: - return "extension"; - case relationship_t::kComposition: - return "composition"; - case relationship_t::kAggregation: - return "aggregation"; - case relationship_t::kContainment: - return "containment"; - case relationship_t::kOwnership: - return "ownership"; - case relationship_t::kAssociation: - return "association"; - case relationship_t::kInstantiation: - return "instantiation"; - case relationship_t::kFriendship: - return "frendship"; - case relationship_t::kDependency: - return "dependency"; - default: - return "invalid"; + case relationship_t::kNone: + return "none"; + case relationship_t::kExtension: + return "extension"; + case relationship_t::kComposition: + return "composition"; + case relationship_t::kAggregation: + return "aggregation"; + case relationship_t::kContainment: + return "containment"; + case relationship_t::kOwnership: + return "ownership"; + case relationship_t::kAssociation: + return "association"; + case relationship_t::kInstantiation: + return "instantiation"; + case relationship_t::kFriendship: + return "frendship"; + case relationship_t::kDependency: + return "dependency"; + default: + return "invalid"; } } - - } } } diff --git a/src/uml/class_diagram_visitor.cc b/src/uml/class_diagram_visitor.cc index 8f7a9ed8..bd3e6e80 100644 --- a/src/uml/class_diagram_visitor.cc +++ b/src/uml/class_diagram_visitor.cc @@ -77,8 +77,8 @@ void tu_visitor::operator()(const cppast::cpp_entity &file) } if (e.kind() == cppast::cpp_entity_kind::class_t) { - spdlog::debug("'{}' - {}", cx::util::full_name(e), - cppast::to_string(e.kind())); + spdlog::debug("========== Visiting '{}' - {}", + cx::util::full_name(e), cppast::to_string(e.kind())); auto &cls = static_cast(e); @@ -86,8 +86,8 @@ void tu_visitor::operator()(const cppast::cpp_entity &file) process_class_declaration(cls); } else if (e.kind() == cppast::cpp_entity_kind::enum_t) { - spdlog::debug("'{}' - {}", cx::util::full_name(e), - cppast::to_string(e.kind())); + spdlog::debug("========== Visiting '{}' - {}", + cx::util::full_name(e), cppast::to_string(e.kind())); auto &enm = static_cast(e); @@ -146,6 +146,7 @@ void tu_visitor::process_class_declaration(const cppast::cpp_class &cls) } else if (child.kind() == cppast::cpp_entity_kind::member_variable_t) { auto &mv = static_cast(child); + spdlog::debug("Found member variable {}", mv.name()); process_field(mv, c, last_access_specifier); } else if (child.kind() == cppast::cpp_entity_kind::variable_t) { @@ -168,11 +169,10 @@ void tu_visitor::process_class_declaration(const cppast::cpp_class &cls) auto &mc = static_cast(child); process_destructor(mc, c, last_access_specifier); } - else if (child.kind() == cppast::cpp_entity_kind::friend_t) { + else if (child.kind() == cppast::cpp_entity_kind::friend_t) { auto &fr = static_cast(child); - spdlog::debug("Found friend declaration: {}, {}", - child.name(), + spdlog::debug("Found friend declaration: {}, {}", child.name(), child.scope_name() ? child.scope_name().value().name() : ""); @@ -187,8 +187,8 @@ void tu_visitor::process_class_declaration(const cppast::cpp_class &cls) process_friend(fr, c); } else { - spdlog::debug("Found some other class child: {} ({})", - child.name(), cppast::to_string(child.kind())); + spdlog::debug("Found some other class child: {} ({})", child.name(), + cppast::to_string(child.kind())); } } @@ -217,10 +217,13 @@ void tu_visitor::process_class_declaration(const cppast::cpp_class &cls) // Process class template arguments if (cppast::is_templated(cls)) { + spdlog::debug("Processing class template parameters..."); auto scope = cppast::cpp_scope_name(type_safe::ref(cls)); for (const auto &tp : scope.template_parameters()) { if (tp.kind() == cppast::cpp_entity_kind::template_type_parameter_t) { + spdlog::debug( + "Processing template type parameter {}", tp.name()); process_template_type_parameter( static_cast( tp), @@ -228,6 +231,8 @@ void tu_visitor::process_class_declaration(const cppast::cpp_class &cls) } else if (tp.kind() == cppast::cpp_entity_kind::non_type_template_parameter_t) { + spdlog::debug( + "Processing template nontype parameter {}", tp.name()); process_template_nontype_parameter( static_cast< const cppast::cpp_non_type_template_parameter &>(tp), @@ -235,6 +240,8 @@ void tu_visitor::process_class_declaration(const cppast::cpp_class &cls) } else if (tp.kind() == cppast::cpp_entity_kind::template_template_parameter_t) { + spdlog::debug( + "Processing template template parameter {}", tp.name()); process_template_template_parameter( static_cast< const cppast::cpp_template_template_parameter &>(tp), @@ -281,7 +288,14 @@ void tu_visitor::process_field(const cppast::cpp_member_variable &mv, class_ &c, m.is_static = false; const auto &tr = cx::util::unreferenced(mv.type()); + + spdlog::debug( + "Processing field with unreferenced type of kind {}", tr.kind()); + if (tr.kind() == cppast::cpp_type_kind::template_instantiation_t) { + spdlog::debug("Processing field with template instatiation type {}", + cppast::to_string(tr)); + const auto &template_instantiation_type = static_cast(tr); if (template_instantiation_type.primary_template() @@ -325,6 +339,11 @@ void tu_visitor::process_field(const cppast::cpp_member_variable &mv, class_ &c, } } } + else if (tr.kind() == cppast::cpp_type_kind::unexposed_t) { + spdlog::debug( + "Processing field with unexposed type {}", cppast::to_string(tr)); + // TODO + } if (mv.type().kind() != cppast::cpp_type_kind::builtin_t) { std::vector> relationships; @@ -614,8 +633,9 @@ void tu_visitor::find_relationships(const cppast::cpp_type &t_, } else { for (const auto &arg : args) { - find_relationships( - arg.type().value(), relationships, relationship_type); + if (arg.type()) + find_relationships( + arg.type().value(), relationships, relationship_type); } } } @@ -675,6 +695,11 @@ class_ tu_visitor::build_template_instantiation(const cppast::cpp_entity &e, ct.type = static_cast(exp) .value(); + else if (exp.kind() == cppast::cpp_expression_kind::unexposed_t) + ct.type = + static_cast(exp) + .expression() + .as_string(); } spdlog::debug("Adding template argument '{}'", ct.type); diff --git a/src/uml/sequence_diagram_visitor.h b/src/uml/sequence_diagram_visitor.h index 44f30140..7ee9bd0f 100644 --- a/src/uml/sequence_diagram_visitor.h +++ b/src/uml/sequence_diagram_visitor.h @@ -65,100 +65,97 @@ static enum CXChildVisitResult translation_unit_visitor( } switch (cursor.kind()) { - case CXCursor_FunctionTemplate: - case CXCursor_CXXMethod: - case CXCursor_FunctionDecl: - ctx->current_method = cursor; - ret = CXChildVisit_Recurse; - break; - case CXCursor_CallExpr: { - auto referenced = cursor.referenced(); - auto referenced_type = referenced.type(); - auto referenced_cursor_name = referenced.display_name(); + case CXCursor_FunctionTemplate: + case CXCursor_CXXMethod: + case CXCursor_FunctionDecl: + ctx->current_method = cursor; + ret = CXChildVisit_Recurse; + break; + case CXCursor_CallExpr: { + auto referenced = cursor.referenced(); + auto referenced_type = referenced.type(); + auto referenced_cursor_name = referenced.display_name(); - auto semantic_parent = referenced.semantic_parent(); - auto sp_name = semantic_parent.fully_qualified(); - auto lexical_parent = cursor.lexical_parent(); - auto lp_name = lexical_parent.spelling(); + auto semantic_parent = referenced.semantic_parent(); + auto sp_name = semantic_parent.fully_qualified(); + auto lexical_parent = cursor.lexical_parent(); + auto lp_name = lexical_parent.spelling(); - CXFile f; - unsigned int line{}; - unsigned int column{}; - unsigned int offset{}; - clang_getFileLocation( - cursor.location(), &f, &line, &column, &offset); - std::string file{clang_getCString(clang_getFileName(f))}; + CXFile f; + unsigned int line{}; + unsigned int column{}; + unsigned int offset{}; + clang_getFileLocation(cursor.location(), &f, &line, &column, &offset); + std::string file{clang_getCString(clang_getFileName(f))}; - auto &d = ctx->d; - auto &config = ctx->config; - if (referenced.kind() == CXCursor_CXXMethod) { - if (config.should_include(sp_name)) { - // Get calling object - std::string caller{}; - if (ctx->current_method.semantic_parent() - .is_translation_unit() || - ctx->current_method.semantic_parent().is_namespace()) { - caller = ctx->current_method.semantic_parent() - .fully_qualified() + - "::" + ctx->current_method.spelling() + "()"; - } - else { - caller = ctx->current_method.semantic_parent() - .fully_qualified(); - } - - auto caller_usr = ctx->current_method.usr(); - // Get called object - auto callee = - referenced.semantic_parent().fully_qualified(); - auto callee_usr = referenced.semantic_parent().usr(); - - // Get called method - auto called_message = cursor.spelling(); - - // Found method call: CXCursorKind () const - spdlog::debug( - "Adding method call at line {}:{} to diagram {}" - "\n\tCURRENT_METHOD: {}\n\tFROM: '{}'\n\tTO: " - "{}\n\tMESSAGE: {}\n\tFROM_USR: {}\n\tTO_USR: " - "{}\n\tRETURN_TYPE: {}", - file, line, d.name, ctx->current_method.spelling(), - caller, callee, called_message, caller_usr, callee_usr, - referenced.type().result_type().spelling()); - - message m; - m.type = message_t::kCall; - m.from = caller; - m.from_usr = caller_usr; - m.line = line; - m.to = callee; - m.to_usr = referenced.usr(); - m.message = called_message; - m.return_type = referenced.type().result_type().spelling(); - - if (d.sequences.find(caller_usr) == d.sequences.end()) { - activity a; - a.usr = caller_usr; - a.from = caller; - d.sequences.insert({caller_usr, std::move(a)}); - } - - d.sequences[caller_usr].messages.emplace_back(std::move(m)); + auto &d = ctx->d; + auto &config = ctx->config; + if (referenced.kind() == CXCursor_CXXMethod) { + if (config.should_include(sp_name)) { + // Get calling object + std::string caller{}; + if (ctx->current_method.semantic_parent() + .is_translation_unit() || + ctx->current_method.semantic_parent().is_namespace()) { + caller = ctx->current_method.semantic_parent() + .fully_qualified() + + "::" + ctx->current_method.spelling() + "()"; + } + else { + caller = + ctx->current_method.semantic_parent().fully_qualified(); } - } - else if (referenced.kind() == CXCursor_FunctionDecl) { - // TODO - } - ret = CXChildVisit_Recurse; - break; + auto caller_usr = ctx->current_method.usr(); + // Get called object + auto callee = referenced.semantic_parent().fully_qualified(); + auto callee_usr = referenced.semantic_parent().usr(); + + // Get called method + auto called_message = cursor.spelling(); + + // Found method call: CXCursorKind () const + spdlog::debug("Adding method call at line {}:{} to diagram {}" + "\n\tCURRENT_METHOD: {}\n\tFROM: '{}'\n\tTO: " + "{}\n\tMESSAGE: {}\n\tFROM_USR: {}\n\tTO_USR: " + "{}\n\tRETURN_TYPE: {}", + file, line, d.name, ctx->current_method.spelling(), caller, + callee, called_message, caller_usr, callee_usr, + referenced.type().result_type().spelling()); + + message m; + m.type = message_t::kCall; + m.from = caller; + m.from_usr = caller_usr; + m.line = line; + m.to = callee; + m.to_usr = referenced.usr(); + m.message = called_message; + m.return_type = referenced.type().result_type().spelling(); + + if (d.sequences.find(caller_usr) == d.sequences.end()) { + activity a; + a.usr = caller_usr; + a.from = caller; + d.sequences.insert({caller_usr, std::move(a)}); + } + + d.sequences[caller_usr].messages.emplace_back(std::move(m)); + } } - case CXCursor_Namespace: { - ret = CXChildVisit_Recurse; - break; + else if (referenced.kind() == CXCursor_FunctionDecl) { + // TODO } - default: - ret = CXChildVisit_Recurse; + + ret = CXChildVisit_Recurse; + break; + } + case CXCursor_Namespace: { + ret = CXChildVisit_Recurse; + break; + } + default: + ret = CXChildVisit_Recurse; } return ret; diff --git a/tests/catch.h b/tests/catch.h index 4ca67455..9a6a49f9 100644 --- a/tests/catch.h +++ b/tests/catch.h @@ -11426,43 +11426,42 @@ public: void use(Colour::Code _colourCode) override { switch (_colourCode) { - case Colour::None: - return setTextAttribute(originalForegroundAttributes); - case Colour::White: - return setTextAttribute( - FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE); - case Colour::Red: - return setTextAttribute(FOREGROUND_RED); - case Colour::Green: - return setTextAttribute(FOREGROUND_GREEN); - case Colour::Blue: - return setTextAttribute(FOREGROUND_BLUE); - case Colour::Cyan: - return setTextAttribute(FOREGROUND_BLUE | FOREGROUND_GREEN); - case Colour::Yellow: - return setTextAttribute(FOREGROUND_RED | FOREGROUND_GREEN); - case Colour::Grey: - return setTextAttribute(0); + case Colour::None: + return setTextAttribute(originalForegroundAttributes); + case Colour::White: + return setTextAttribute( + FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE); + case Colour::Red: + return setTextAttribute(FOREGROUND_RED); + case Colour::Green: + return setTextAttribute(FOREGROUND_GREEN); + case Colour::Blue: + return setTextAttribute(FOREGROUND_BLUE); + case Colour::Cyan: + return setTextAttribute(FOREGROUND_BLUE | FOREGROUND_GREEN); + case Colour::Yellow: + return setTextAttribute(FOREGROUND_RED | FOREGROUND_GREEN); + case Colour::Grey: + return setTextAttribute(0); - case Colour::LightGrey: - return setTextAttribute(FOREGROUND_INTENSITY); - case Colour::BrightRed: - return setTextAttribute(FOREGROUND_INTENSITY | FOREGROUND_RED); - case Colour::BrightGreen: - return setTextAttribute( - FOREGROUND_INTENSITY | FOREGROUND_GREEN); - case Colour::BrightWhite: - return setTextAttribute(FOREGROUND_INTENSITY | - FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE); - case Colour::BrightYellow: - return setTextAttribute( - FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN); + case Colour::LightGrey: + return setTextAttribute(FOREGROUND_INTENSITY); + case Colour::BrightRed: + return setTextAttribute(FOREGROUND_INTENSITY | FOREGROUND_RED); + case Colour::BrightGreen: + return setTextAttribute(FOREGROUND_INTENSITY | FOREGROUND_GREEN); + case Colour::BrightWhite: + return setTextAttribute(FOREGROUND_INTENSITY | FOREGROUND_GREEN | + FOREGROUND_RED | FOREGROUND_BLUE); + case Colour::BrightYellow: + return setTextAttribute( + FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN); - case Colour::Bright: - CATCH_INTERNAL_ERROR("not a colour"); + case Colour::Bright: + CATCH_INTERNAL_ERROR("not a colour"); - default: - CATCH_ERROR("Unknown colour requested"); + default: + CATCH_ERROR("Unknown colour requested"); } } @@ -11509,37 +11508,37 @@ public: void use(Colour::Code _colourCode) override { switch (_colourCode) { - case Colour::None: - case Colour::White: - return setColour("[0m"); - case Colour::Red: - return setColour("[0;31m"); - case Colour::Green: - return setColour("[0;32m"); - case Colour::Blue: - return setColour("[0;34m"); - case Colour::Cyan: - return setColour("[0;36m"); - case Colour::Yellow: - return setColour("[0;33m"); - case Colour::Grey: - return setColour("[1;30m"); + case Colour::None: + case Colour::White: + return setColour("[0m"); + case Colour::Red: + return setColour("[0;31m"); + case Colour::Green: + return setColour("[0;32m"); + case Colour::Blue: + return setColour("[0;34m"); + case Colour::Cyan: + return setColour("[0;36m"); + case Colour::Yellow: + return setColour("[0;33m"); + case Colour::Grey: + return setColour("[1;30m"); - case Colour::LightGrey: - return setColour("[0;37m"); - case Colour::BrightRed: - return setColour("[1;31m"); - case Colour::BrightGreen: - return setColour("[1;32m"); - case Colour::BrightWhite: - return setColour("[1;37m"); - case Colour::BrightYellow: - return setColour("[1;33m"); + case Colour::LightGrey: + return setColour("[0;37m"); + case Colour::BrightRed: + return setColour("[1;31m"); + case Colour::BrightGreen: + return setColour("[1;32m"); + case Colour::BrightWhite: + return setColour("[1;37m"); + case Colour::BrightYellow: + return setColour("[1;33m"); - case Colour::Bright: - CATCH_INTERNAL_ERROR("not a colour"); - default: - CATCH_INTERNAL_ERROR("Unknown colour requested"); + case Colour::Bright: + CATCH_INTERNAL_ERROR("not a colour"); + default: + CATCH_INTERNAL_ERROR("Unknown colour requested"); } } static IColourImpl *instance() @@ -12965,13 +12964,13 @@ WithinUlpsMatcher::WithinUlpsMatcher( bool WithinUlpsMatcher::match(double const &matchee) const { switch (m_type) { - case FloatingPointKind::Float: - return almostEqualUlps(static_cast(matchee), - static_cast(m_target), m_ulps); - case FloatingPointKind::Double: - return almostEqualUlps(matchee, m_target, m_ulps); - default: - CATCH_INTERNAL_ERROR("Unknown FloatingPointKind value"); + case FloatingPointKind::Float: + return almostEqualUlps( + static_cast(matchee), static_cast(m_target), m_ulps); + case FloatingPointKind::Double: + return almostEqualUlps(matchee, m_target, m_ulps); + default: + CATCH_INTERNAL_ERROR("Unknown FloatingPointKind value"); } } @@ -13340,32 +13339,32 @@ Capturer::Capturer(StringRef macroName, SourceLineInfo const &lineInfo, for (size_t pos = 0; pos < names.size(); ++pos) { char c = names[pos]; switch (c) { - case '[': - case '{': - case '(': - // It is basically impossible to disambiguate between - // comparison and start of template args in this context - // case '<': - openings.push(c); - break; - case ']': - case '}': - case ')': - // case '>': - openings.pop(); - break; - case '"': - case '\'': - pos = skipq(pos, c); - break; - case ',': - if (start != pos && openings.empty()) { - m_messages.emplace_back(macroName, lineInfo, resultType); - m_messages.back().message = - static_cast(trimmed(start, pos)); - m_messages.back().message += " := "; - start = pos; - } + case '[': + case '{': + case '(': + // It is basically impossible to disambiguate between + // comparison and start of template args in this context + // case '<': + openings.push(c); + break; + case ']': + case '}': + case ')': + // case '>': + openings.pop(); + break; + case '"': + case '\'': + pos = skipq(pos, c); + break; + case ',': + if (start != pos && openings.empty()) { + m_messages.emplace_back(macroName, lineInfo, resultType); + m_messages.back().message = + static_cast(trimmed(start, pos)); + m_messages.back().message += " := "; + start = pos; + } } } assert(openings.empty() && "Mismatched openings"); @@ -15763,16 +15762,16 @@ std::vector sortTests( std::vector sorted = unsortedTestCases; switch (config.runOrder()) { - case RunTests::InLexicographicalOrder: - std::sort(sorted.begin(), sorted.end()); - break; - case RunTests::InRandomOrder: - seedRng(config); - std::shuffle(sorted.begin(), sorted.end(), rng()); - break; - case RunTests::InDeclarationOrder: - // already in declaration order - break; + case RunTests::InLexicographicalOrder: + std::sort(sorted.begin(), sorted.end()); + break; + case RunTests::InRandomOrder: + seedRng(config); + std::shuffle(sorted.begin(), sorted.end(), rng()); + break; + case RunTests::InDeclarationOrder: + // already in declaration order + break; } return sorted; } @@ -16005,25 +16004,25 @@ void TrackerBase::close() m_ctx.currentTracker().close(); switch (m_runState) { - case NeedsAnotherRun: - break; + case NeedsAnotherRun: + break; - case Executing: + case Executing: + m_runState = CompletedSuccessfully; + break; + case ExecutingChildren: + if (std::all_of(m_children.begin(), m_children.end(), + [](ITrackerPtr const &t) { return t->isComplete(); })) m_runState = CompletedSuccessfully; - break; - case ExecutingChildren: - if (std::all_of(m_children.begin(), m_children.end(), - [](ITrackerPtr const &t) { return t->isComplete(); })) - m_runState = CompletedSuccessfully; - break; + break; - case NotStarted: - case CompletedSuccessfully: - case Failed: - CATCH_INTERNAL_ERROR("Illogical state: " << m_runState); + case NotStarted: + case CompletedSuccessfully: + case Failed: + CATCH_INTERNAL_ERROR("Illogical state: " << m_runState); - default: - CATCH_INTERNAL_ERROR("Unknown state: " << m_runState); + default: + CATCH_INTERNAL_ERROR("Unknown state: " << m_runState); } moveToParent(); m_ctx.completeCycle(); @@ -16304,23 +16303,23 @@ bool TestSpecParser::visitChar(char c) } switch (m_mode) { - case None: - if (processNoneChar(c)) - return true; - break; - case Name: - processNameChar(c); - break; - case EscapedName: - endMode(); - addCharToPattern(c); + case None: + if (processNoneChar(c)) return true; - default: - case Tag: - case QuotedName: - if (processOtherChar(c)) - return true; - break; + break; + case Name: + processNameChar(c); + break; + case EscapedName: + endMode(); + addCharToPattern(c); + return true; + default: + case Tag: + case QuotedName: + if (processOtherChar(c)) + return true; + break; } m_substring += c; @@ -16335,20 +16334,20 @@ bool TestSpecParser::visitChar(char c) bool TestSpecParser::processNoneChar(char c) { switch (c) { - case ' ': - return true; - case '~': - m_exclusion = true; - return false; - case '[': - startNewMode(Tag); - return false; - case '"': - startNewMode(QuotedName); - return false; - default: - startNewMode(Name); - return false; + case ' ': + return true; + case '~': + m_exclusion = true; + return false; + case '[': + startNewMode(Tag); + return false; + case '"': + startNewMode(QuotedName); + return false; + default: + startNewMode(Name); + return false; } } void TestSpecParser::processNameChar(char c) @@ -16373,17 +16372,17 @@ void TestSpecParser::startNewMode(Mode mode) { m_mode = mode; } void TestSpecParser::endMode() { switch (m_mode) { - case Name: - case QuotedName: - return addNamePattern(); - case Tag: - return addTagPattern(); - case EscapedName: - revertBackToLastMode(); - return; - case None: - default: - return startNewMode(None); + case Name: + case QuotedName: + return addNamePattern(); + case Tag: + return addTagPattern(); + case EscapedName: + revertBackToLastMode(); + return; + case None: + default: + return startNewMode(None); } } void TestSpecParser::escape() @@ -16395,18 +16394,18 @@ void TestSpecParser::escape() bool TestSpecParser::isControlChar(char c) const { switch (m_mode) { - default: - return false; - case None: - return c == '~'; - case Name: - return c == '['; - case EscapedName: - return true; - case QuotedName: - return c == '"'; - case Tag: - return c == '[' || c == ']'; + default: + return false; + case None: + return c == '~'; + case Name: + return c == '['; + case EscapedName: + return true; + case QuotedName: + return c == '"'; + case Tag: + return c == '[' || c == ']'; } } @@ -16671,15 +16670,15 @@ std::string StringMaker::convert(const std::string &str) std::string s("\""); for (char c : str) { switch (c) { - case '\n': - s.append("\\n"); - break; - case '\t': - s.append("\\t"); - break; - default: - s.push_back(c); - break; + case '\n': + s.append("\\n"); + break; + case '\t': + s.append("\\t"); + break; + default: + s.push_back(c); + break; } } s.append("\""); @@ -16987,16 +16986,16 @@ WildcardPattern::WildcardPattern( bool WildcardPattern::matches(std::string const &str) const { switch (m_wildcard) { - case NoWildcard: - return m_pattern == normaliseString(str); - case WildcardAtStart: - return endsWith(normaliseString(str), m_pattern); - case WildcardAtEnd: - return startsWith(normaliseString(str), m_pattern); - case WildcardAtBothEnds: - return contains(normaliseString(str), m_pattern); - default: - CATCH_INTERNAL_ERROR("Unknown enum"); + case NoWildcard: + return m_pattern == normaliseString(str); + case WildcardAtStart: + return endsWith(normaliseString(str), m_pattern); + case WildcardAtEnd: + return startsWith(normaliseString(str), m_pattern); + case WildcardAtBothEnds: + return contains(normaliseString(str), m_pattern); + default: + CATCH_INTERNAL_ERROR("Unknown enum"); } } @@ -17093,94 +17092,94 @@ void XmlEncode::encodeTo(std::ostream &os) const for (std::size_t idx = 0; idx < m_str.size(); ++idx) { unsigned char c = m_str[idx]; switch (c) { - case '<': - os << "<"; + case '<': + os << "<"; + break; + case '&': + os << "&"; + break; + + case '>': + // See: http://www.w3.org/TR/xml/#syntax + if (idx > 2 && m_str[idx - 1] == ']' && m_str[idx - 2] == ']') + os << ">"; + else + os << c; + break; + + case '\"': + if (m_forWhat == ForAttributes) + os << """; + else + os << c; + break; + + default: + // Check for control characters and invalid utf-8 + + // Escape control characters in standard ascii + // see + // http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0 + if (c < 0x09 || (c > 0x0D && c < 0x20) || c == 0x7F) { + hexEscapeChar(os, c); break; - case '&': - os << "&"; + } + + // Plain ASCII: Write it to stream + if (c < 0x7F) { + os << c; break; + } - case '>': - // See: http://www.w3.org/TR/xml/#syntax - if (idx > 2 && m_str[idx - 1] == ']' && m_str[idx - 2] == ']') - os << ">"; - else - os << c; + // UTF-8 territory + // Check if the encoding is valid and if it is not, hex escape + // bytes. Important: We do not check the exact decoded values + // for validity, only the encoding format First check that this + // bytes is a valid lead byte: This means that it is not encoded + // as 1111 1XXX Or as 10XX XXXX + if (c < 0xC0 || c >= 0xF8) { + hexEscapeChar(os, c); break; + } - case '\"': - if (m_forWhat == ForAttributes) - os << """; - else - os << c; + auto encBytes = trailingBytes(c); + // Are there enough bytes left to avoid accessing out-of-bounds + // memory? + if (idx + encBytes - 1 >= m_str.size()) { + hexEscapeChar(os, c); break; + } + // The header is valid, check data + // The next encBytes bytes must together be a valid utf-8 + // This means: bitpattern 10XX XXXX and the extracted value is + // sane (ish) + bool valid = true; + uint32_t value = headerValue(c); + for (std::size_t n = 1; n < encBytes; ++n) { + unsigned char nc = m_str[idx + n]; + valid &= ((nc & 0xC0) == 0x80); + value = (value << 6) | (nc & 0x3F); + } - default: - // Check for control characters and invalid utf-8 - - // Escape control characters in standard ascii - // see - // http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0 - if (c < 0x09 || (c > 0x0D && c < 0x20) || c == 0x7F) { - hexEscapeChar(os, c); - break; - } - - // Plain ASCII: Write it to stream - if (c < 0x7F) { - os << c; - break; - } - - // UTF-8 territory - // Check if the encoding is valid and if it is not, hex escape - // bytes. Important: We do not check the exact decoded values - // for validity, only the encoding format First check that this - // bytes is a valid lead byte: This means that it is not encoded - // as 1111 1XXX Or as 10XX XXXX - if (c < 0xC0 || c >= 0xF8) { - hexEscapeChar(os, c); - break; - } - - auto encBytes = trailingBytes(c); - // Are there enough bytes left to avoid accessing out-of-bounds - // memory? - if (idx + encBytes - 1 >= m_str.size()) { - hexEscapeChar(os, c); - break; - } - // The header is valid, check data - // The next encBytes bytes must together be a valid utf-8 - // This means: bitpattern 10XX XXXX and the extracted value is - // sane (ish) - bool valid = true; - uint32_t value = headerValue(c); - for (std::size_t n = 1; n < encBytes; ++n) { - unsigned char nc = m_str[idx + n]; - valid &= ((nc & 0xC0) == 0x80); - value = (value << 6) | (nc & 0x3F); - } - - if ( - // Wrong bit pattern of following bytes - (!valid) || - // Overlong encodings - (value < 0x80) || - (0x80 <= value && value < 0x800 && encBytes > 2) || - (0x800 < value && value < 0x10000 && encBytes > 3) || - // Encoded value out of range - (value >= 0x110000)) { - hexEscapeChar(os, c); - break; - } - - // If we got here, this is in fact a valid(ish) utf-8 sequence - for (std::size_t n = 0; n < encBytes; ++n) { - os << m_str[idx + n]; - } - idx += encBytes - 1; + if ( + // Wrong bit pattern of following bytes + (!valid) || + // Overlong encodings + (value < 0x80) || + (0x80 <= value && value < 0x800 && encBytes > 2) || + (0x800 < value && value < 0x10000 && encBytes > 3) || + // Encoded value out of range + (value >= 0x110000)) { + hexEscapeChar(os, c); break; + } + + // If we got here, this is in fact a valid(ish) utf-8 sequence + for (std::size_t n = 0; n < encBytes; ++n) { + os << m_str[idx + n]; + } + idx += encBytes - 1; + break; } } } @@ -17528,66 +17527,66 @@ public: itMessage = messages.begin(); switch (result.getResultType()) { - case ResultWas::Ok: - printResultType(Colour::ResultSuccess, passedString()); - printOriginalExpression(); - printReconstructedExpression(); - if (!result.hasExpression()) - printRemainingMessages(Colour::None); - else - printRemainingMessages(); - break; - case ResultWas::ExpressionFailed: - if (result.isOk()) - printResultType(Colour::ResultSuccess, - failedString() + std::string(" - but was ok")); - else - printResultType(Colour::Error, failedString()); - printOriginalExpression(); - printReconstructedExpression(); - printRemainingMessages(); - break; - case ResultWas::ThrewException: - printResultType(Colour::Error, failedString()); - printIssue("unexpected exception with message:"); - printMessage(); - printExpressionWas(); - printRemainingMessages(); - break; - case ResultWas::FatalErrorCondition: - printResultType(Colour::Error, failedString()); - printIssue("fatal error condition with message:"); - printMessage(); - printExpressionWas(); - printRemainingMessages(); - break; - case ResultWas::DidntThrowException: - printResultType(Colour::Error, failedString()); - printIssue("expected exception, got none"); - printExpressionWas(); - printRemainingMessages(); - break; - case ResultWas::Info: - printResultType(Colour::None, "info"); - printMessage(); - printRemainingMessages(); - break; - case ResultWas::Warning: - printResultType(Colour::None, "warning"); - printMessage(); - printRemainingMessages(); - break; - case ResultWas::ExplicitFailure: - printResultType(Colour::Error, failedString()); - printIssue("explicitly"); + case ResultWas::Ok: + printResultType(Colour::ResultSuccess, passedString()); + printOriginalExpression(); + printReconstructedExpression(); + if (!result.hasExpression()) printRemainingMessages(Colour::None); - break; - // These cases are here to prevent compiler warnings - case ResultWas::Unknown: - case ResultWas::FailureBit: - case ResultWas::Exception: - printResultType(Colour::Error, "** internal error **"); - break; + else + printRemainingMessages(); + break; + case ResultWas::ExpressionFailed: + if (result.isOk()) + printResultType(Colour::ResultSuccess, + failedString() + std::string(" - but was ok")); + else + printResultType(Colour::Error, failedString()); + printOriginalExpression(); + printReconstructedExpression(); + printRemainingMessages(); + break; + case ResultWas::ThrewException: + printResultType(Colour::Error, failedString()); + printIssue("unexpected exception with message:"); + printMessage(); + printExpressionWas(); + printRemainingMessages(); + break; + case ResultWas::FatalErrorCondition: + printResultType(Colour::Error, failedString()); + printIssue("fatal error condition with message:"); + printMessage(); + printExpressionWas(); + printRemainingMessages(); + break; + case ResultWas::DidntThrowException: + printResultType(Colour::Error, failedString()); + printIssue("expected exception, got none"); + printExpressionWas(); + printRemainingMessages(); + break; + case ResultWas::Info: + printResultType(Colour::None, "info"); + printMessage(); + printRemainingMessages(); + break; + case ResultWas::Warning: + printResultType(Colour::None, "warning"); + printMessage(); + printRemainingMessages(); + break; + case ResultWas::ExplicitFailure: + printResultType(Colour::Error, failedString()); + printIssue("explicitly"); + printRemainingMessages(Colour::None); + break; + // These cases are here to prevent compiler warnings + case ResultWas::Unknown: + case ResultWas::FailureBit: + case ResultWas::Exception: + printResultType(Colour::Error, "** internal error **"); + break; } } @@ -17786,70 +17785,70 @@ public: , printInfoMessages(_printInfoMessages) { switch (result.getResultType()) { - case ResultWas::Ok: + case ResultWas::Ok: + colour = Colour::Success; + passOrFail = "PASSED"; + // if( result.hasMessage() ) + if (_stats.infoMessages.size() == 1) + messageLabel = "with message"; + if (_stats.infoMessages.size() > 1) + messageLabel = "with messages"; + break; + case ResultWas::ExpressionFailed: + if (result.isOk()) { colour = Colour::Success; - passOrFail = "PASSED"; - // if( result.hasMessage() ) - if (_stats.infoMessages.size() == 1) - messageLabel = "with message"; - if (_stats.infoMessages.size() > 1) - messageLabel = "with messages"; - break; - case ResultWas::ExpressionFailed: - if (result.isOk()) { - colour = Colour::Success; - passOrFail = "FAILED - but was ok"; - } - else { - colour = Colour::Error; - passOrFail = "FAILED"; - } - if (_stats.infoMessages.size() == 1) - messageLabel = "with message"; - if (_stats.infoMessages.size() > 1) - messageLabel = "with messages"; - break; - case ResultWas::ThrewException: + passOrFail = "FAILED - but was ok"; + } + else { colour = Colour::Error; passOrFail = "FAILED"; - messageLabel = "due to unexpected exception with "; - if (_stats.infoMessages.size() == 1) - messageLabel += "message"; - if (_stats.infoMessages.size() > 1) - messageLabel += "messages"; - break; - case ResultWas::FatalErrorCondition: - colour = Colour::Error; - passOrFail = "FAILED"; - messageLabel = "due to a fatal error condition"; - break; - case ResultWas::DidntThrowException: - colour = Colour::Error; - passOrFail = "FAILED"; - messageLabel = - "because no exception was thrown where one was expected"; - break; - case ResultWas::Info: - messageLabel = "info"; - break; - case ResultWas::Warning: - messageLabel = "warning"; - break; - case ResultWas::ExplicitFailure: - passOrFail = "FAILED"; - colour = Colour::Error; - if (_stats.infoMessages.size() == 1) - messageLabel = "explicitly with message"; - if (_stats.infoMessages.size() > 1) - messageLabel = "explicitly with messages"; - break; - // These cases are here to prevent compiler warnings - case ResultWas::Unknown: - case ResultWas::FailureBit: - case ResultWas::Exception: - passOrFail = "** internal error **"; - colour = Colour::Error; - break; + } + if (_stats.infoMessages.size() == 1) + messageLabel = "with message"; + if (_stats.infoMessages.size() > 1) + messageLabel = "with messages"; + break; + case ResultWas::ThrewException: + colour = Colour::Error; + passOrFail = "FAILED"; + messageLabel = "due to unexpected exception with "; + if (_stats.infoMessages.size() == 1) + messageLabel += "message"; + if (_stats.infoMessages.size() > 1) + messageLabel += "messages"; + break; + case ResultWas::FatalErrorCondition: + colour = Colour::Error; + passOrFail = "FAILED"; + messageLabel = "due to a fatal error condition"; + break; + case ResultWas::DidntThrowException: + colour = Colour::Error; + passOrFail = "FAILED"; + messageLabel = + "because no exception was thrown where one was expected"; + break; + case ResultWas::Info: + messageLabel = "info"; + break; + case ResultWas::Warning: + messageLabel = "warning"; + break; + case ResultWas::ExplicitFailure: + passOrFail = "FAILED"; + colour = Colour::Error; + if (_stats.infoMessages.size() == 1) + messageLabel = "explicitly with message"; + if (_stats.infoMessages.size() > 1) + messageLabel = "explicitly with messages"; + break; + // These cases are here to prevent compiler warnings + case ResultWas::Unknown: + case ResultWas::FailureBit: + case ResultWas::Exception: + passOrFail = "** internal error **"; + colour = Colour::Error; + break; } } @@ -17988,37 +17987,37 @@ public: auto value() const -> double { switch (m_units) { - case Unit::Microseconds: - return m_inNanoseconds / - static_cast(s_nanosecondsInAMicrosecond); - case Unit::Milliseconds: - return m_inNanoseconds / - static_cast(s_nanosecondsInAMillisecond); - case Unit::Seconds: - return m_inNanoseconds / - static_cast(s_nanosecondsInASecond); - case Unit::Minutes: - return m_inNanoseconds / - static_cast(s_nanosecondsInAMinute); - default: - return m_inNanoseconds; + case Unit::Microseconds: + return m_inNanoseconds / + static_cast(s_nanosecondsInAMicrosecond); + case Unit::Milliseconds: + return m_inNanoseconds / + static_cast(s_nanosecondsInAMillisecond); + case Unit::Seconds: + return m_inNanoseconds / + static_cast(s_nanosecondsInASecond); + case Unit::Minutes: + return m_inNanoseconds / + static_cast(s_nanosecondsInAMinute); + default: + return m_inNanoseconds; } } auto unitsAsString() const -> std::string { switch (m_units) { - case Unit::Nanoseconds: - return "ns"; - case Unit::Microseconds: - return "us"; - case Unit::Milliseconds: - return "ms"; - case Unit::Seconds: - return "s"; - case Unit::Minutes: - return "m"; - default: - return "** internal error **"; + case Unit::Nanoseconds: + return "ns"; + case Unit::Microseconds: + return "us"; + case Unit::Milliseconds: + return "ms"; + case Unit::Seconds: + return "s"; + case Unit::Minutes: + return "m"; + default: + return "** internal error **"; } } friend auto operator<<(std::ostream &os, Duration const &duration) @@ -18742,25 +18741,25 @@ void JunitReporter::writeAssertion(AssertionStats const &stats) if (!result.isOk()) { std::string elementName; switch (result.getResultType()) { - case ResultWas::ThrewException: - case ResultWas::FatalErrorCondition: - elementName = "error"; - break; - case ResultWas::ExplicitFailure: - case ResultWas::ExpressionFailed: - case ResultWas::DidntThrowException: - elementName = "failure"; - break; + case ResultWas::ThrewException: + case ResultWas::FatalErrorCondition: + elementName = "error"; + break; + case ResultWas::ExplicitFailure: + case ResultWas::ExpressionFailed: + case ResultWas::DidntThrowException: + elementName = "failure"; + break; - // We should never see these here: - case ResultWas::Info: - case ResultWas::Warning: - case ResultWas::Ok: - case ResultWas::Unknown: - case ResultWas::FailureBit: - case ResultWas::Exception: - elementName = "internalError"; - break; + // We should never see these here: + case ResultWas::Info: + case ResultWas::Warning: + case ResultWas::Ok: + case ResultWas::Unknown: + case ResultWas::FailureBit: + case ResultWas::Exception: + elementName = "internalError"; + break; } XmlWriter::ScopedElement e = xml.scopedElement(elementName); @@ -19105,32 +19104,32 @@ bool XmlReporter::assertionEnded(AssertionStats const &assertionStats) // And... Print a result applicable to each result type. switch (result.getResultType()) { - case ResultWas::ThrewException: - m_xml.startElement("Exception"); - writeSourceInfo(result.getSourceInfo()); - m_xml.writeText(result.getMessage()); - m_xml.endElement(); - break; - case ResultWas::FatalErrorCondition: - m_xml.startElement("FatalErrorCondition"); - writeSourceInfo(result.getSourceInfo()); - m_xml.writeText(result.getMessage()); - m_xml.endElement(); - break; - case ResultWas::Info: - m_xml.scopedElement("Info").writeText(result.getMessage()); - break; - case ResultWas::Warning: - // Warning will already have been written - break; - case ResultWas::ExplicitFailure: - m_xml.startElement("Failure"); - writeSourceInfo(result.getSourceInfo()); - m_xml.writeText(result.getMessage()); - m_xml.endElement(); - break; - default: - break; + case ResultWas::ThrewException: + m_xml.startElement("Exception"); + writeSourceInfo(result.getSourceInfo()); + m_xml.writeText(result.getMessage()); + m_xml.endElement(); + break; + case ResultWas::FatalErrorCondition: + m_xml.startElement("FatalErrorCondition"); + writeSourceInfo(result.getSourceInfo()); + m_xml.writeText(result.getMessage()); + m_xml.endElement(); + break; + case ResultWas::Info: + m_xml.scopedElement("Info").writeText(result.getMessage()); + break; + case ResultWas::Warning: + // Warning will already have been written + break; + case ResultWas::ExplicitFailure: + m_xml.startElement("Failure"); + writeSourceInfo(result.getSourceInfo()); + m_xml.writeText(result.getMessage()); + m_xml.endElement(); + break; + default: + break; } if (result.hasExpression()) diff --git a/tests/t00003/test_case.h b/tests/t00003/test_case.h index 41bba51b..c0251992 100644 --- a/tests/t00003/test_case.h +++ b/tests/t00003/test_case.h @@ -56,7 +56,8 @@ TEST_CASE("t00003", "[test-case][class]") REQUIRE_THAT(puml, IsField(Public("int public_member"))); REQUIRE_THAT(puml, IsField(Protected("int protected_member"))); REQUIRE_THAT(puml, IsField(Private("int private_member"))); - REQUIRE_THAT(puml, IsField(Static(Public("unsigned long const auto_member")))); + REQUIRE_THAT( + puml, IsField(Static(Public("unsigned long const auto_member")))); REQUIRE_THAT(puml, IsField(Private("int a"))); REQUIRE_THAT(puml, IsField(Private("int b"))); diff --git a/tests/t00009/test_case.h b/tests/t00009/test_case.h index 2235b9f1..c5014cae 100644 --- a/tests/t00009/test_case.h +++ b/tests/t00009/test_case.h @@ -48,8 +48,7 @@ TEST_CASE("t00009", "[test-case][class]") REQUIRE_THAT(puml, IsField(Public("T value"))); REQUIRE_THAT(puml, IsField(Public("A aint"))); REQUIRE_THAT(puml, IsField(Public("A* astring"))); - REQUIRE_THAT( - puml, IsField(Public("A>& avector"))); + REQUIRE_THAT(puml, IsField(Public("A>& avector"))); REQUIRE_THAT(puml, IsInstantiation(_A("A"), _A("A"))); REQUIRE_THAT(puml, IsInstantiation(_A("A"), _A("A"))); diff --git a/tests/t00011/test_case.h b/tests/t00011/test_case.h index dfbc5450..14fbfe98 100644 --- a/tests/t00011/test_case.h +++ b/tests/t00011/test_case.h @@ -47,7 +47,7 @@ TEST_CASE("t00011", "[test-case][class]") REQUIRE_THAT(puml, IsClass(_A("D"))); REQUIRE_THAT(puml, IsFriend(_A("A"), _A("B"))); - //REQUIRE_THAT(puml, IsFriend(_A("A"), _A("D"))); + // REQUIRE_THAT(puml, IsFriend(_A("A"), _A("D"))); save_puml( "./" + config.output_directory + "/" + diagram->name + ".puml", puml); diff --git a/tests/t00012/t00012.cc b/tests/t00012/t00012.cc index 5bc5c244..c2a79d73 100644 --- a/tests/t00012/t00012.cc +++ b/tests/t00012/t00012.cc @@ -3,6 +3,7 @@ #include #include #include +#include namespace clanguml { namespace t00012 { diff --git a/tests/t00012/test_case.h b/tests/t00012/test_case.h index 668ed609..388cfb5e 100644 --- a/tests/t00012/test_case.h +++ b/tests/t00012/test_case.h @@ -50,7 +50,7 @@ TEST_CASE("t00012", "[test-case][class]") puml, IsInstantiation(_A("B"), _A("B<1, 1, 1, 1>"))); REQUIRE_THAT(puml, IsInstantiation(_A("C"), - _A("C>>>, 3, 3, " "3>")));