Json::Value CallGraph::to_json()

in source/CallGraph.cpp [700:764]


Json::Value CallGraph::to_json(bool with_overrides) const {
  auto value = Json::Value(Json::objectValue);
  for (const auto& [method, callees] : resolved_base_callees_) {
    auto method_value = Json::Value(Json::objectValue);

    std::unordered_set<const Method*> static_callees;
    std::unordered_set<const Method*> virtual_callees;
    for (const auto& [instruction, resolved_base_callee] : callees) {
      auto call_target = CallTarget::from_call_instruction(
          method,
          instruction,
          resolved_base_callee,
          types_,
          class_hierarchies_,
          overrides_);
      if (!call_target.resolved()) {
        continue;
      } else if (call_target.is_virtual()) {
        virtual_callees.insert(call_target.resolved_base_callee());
        if (with_overrides) {
          for (const auto* override : call_target.overrides()) {
            virtual_callees.insert(override);
          }
        }
      } else {
        static_callees.insert(call_target.resolved_base_callee());
      }
    }

    if (!static_callees.empty()) {
      auto static_callees_value = Json::Value(Json::arrayValue);
      for (const auto* callee : static_callees) {
        static_callees_value.append(Json::Value(show(callee)));
      }
      method_value["static"] = static_callees_value;
    }

    if (!virtual_callees.empty()) {
      auto virtual_callees_value = Json::Value(Json::arrayValue);
      for (const auto* callee : virtual_callees) {
        virtual_callees_value.append(Json::Value(show(callee)));
      }
      method_value["virtual"] = virtual_callees_value;
    }

    value[show(method)] = method_value;
  }
  for (const auto& [method, instruction_artificial_callees] :
       artificial_callees_) {
    std::unordered_set<const Method*> callees;
    for (const auto& [instruction, artificial_callees] :
         instruction_artificial_callees) {
      for (const auto& artificial_callee : artificial_callees) {
        callees.insert(artificial_callee.call_target.resolved_base_callee());
      }
    }

    auto callees_value = Json::Value(Json::arrayValue);
    for (const auto* callee : callees) {
      callees_value.append(Json::Value(show(callee)));
    }
    value[show(method)]["artificial"] = callees_value;
  }
  return value;
}