bool lldb_private::formatters::swift::SwiftOptionalSummaryProvider::DoesPrintChildren (ValueObject* target_valobj) const { if (!target_valobj) return false; ValueObject *some = ExtractSomeIfAny(target_valobj,target_valobj->GetDynamicValueType(),true); if (!some) return true; lldb_private::Flags some_flags(some->GetCompilerType().GetTypeInfo()); if (some_flags.AllSet(eTypeIsSwift | eTypeInstanceIsPointer)) return true; lldb::TypeSummaryImplSP summary_sp = some->GetSummaryFormat(); if (!summary_sp) { if (lldb_private::DataVisualization::ShouldPrintAsOneLiner(*some)) return false; else return (some->GetNumChildren() > 0); } else return (some->GetNumChildren() > 0) && (summary_sp->DoesPrintChildren(some)); }
bool FormatManager::ShouldPrintAsOneLiner(ValueObject &valobj) { // if settings say no oneline whatsoever if (valobj.GetTargetSP().get() && !valobj.GetTargetSP()->GetDebugger().GetAutoOneLineSummaries()) return false; // then don't oneline // if this object has a summary, then ask the summary if (valobj.GetSummaryFormat().get() != nullptr) return valobj.GetSummaryFormat()->IsOneLiner(); // no children, no party if (valobj.GetNumChildren() == 0) return false; // ask the type if it has any opinion about this eLazyBoolCalculate == no // opinion; other values should be self explanatory CompilerType compiler_type(valobj.GetCompilerType()); if (compiler_type.IsValid()) { switch (compiler_type.ShouldPrintAsOneLiner(&valobj)) { case eLazyBoolNo: return false; case eLazyBoolYes: return true; case eLazyBoolCalculate: break; } } size_t total_children_name_len = 0; for (size_t idx = 0; idx < valobj.GetNumChildren(); idx++) { bool is_synth_val = false; ValueObjectSP child_sp(valobj.GetChildAtIndex(idx, true)); // something is wrong here - bail out if (!child_sp) return false; // also ask the child's type if it has any opinion CompilerType child_compiler_type(child_sp->GetCompilerType()); if (child_compiler_type.IsValid()) { switch (child_compiler_type.ShouldPrintAsOneLiner(child_sp.get())) { case eLazyBoolYes: // an opinion of yes is only binding for the child, so keep going case eLazyBoolCalculate: break; case eLazyBoolNo: // but if the child says no, then it's a veto on the whole thing return false; } } // if we decided to define synthetic children for a type, we probably care // enough to show them, but avoid nesting children in children if (child_sp->GetSyntheticChildren().get() != nullptr) { ValueObjectSP synth_sp(child_sp->GetSyntheticValue()); // wait.. wat? just get out of here.. if (!synth_sp) return false; // but if we only have them to provide a value, keep going if (!synth_sp->MightHaveChildren() && synth_sp->DoesProvideSyntheticValue()) is_synth_val = true; else return false; } total_children_name_len += child_sp->GetName().GetLength(); // 50 itself is a "randomly" chosen number - the idea is that // overly long structs should not get this treatment // FIXME: maybe make this a user-tweakable setting? if (total_children_name_len > 50) return false; // if a summary is there.. if (child_sp->GetSummaryFormat()) { // and it wants children, then bail out if (child_sp->GetSummaryFormat()->DoesPrintChildren(child_sp.get())) return false; } // if this child has children.. if (child_sp->GetNumChildren()) { // ...and no summary... // (if it had a summary and the summary wanted children, we would have // bailed out anyway // so this only makes us bail out if this has no summary and we would // then print children) if (!child_sp->GetSummaryFormat() && !is_synth_val) // but again only do // that if not a // synthetic valued // child return false; // then bail out } } return true; }