TypeCategory.cpp revision 263367
1//===-- TypeCategory.cpp -------------------------------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lldb/lldb-python.h"
11
12#include "lldb/DataFormatters/TypeCategory.h"
13
14// C Includes
15// C++ Includes
16// Other libraries and framework includes
17// Project includes
18
19using namespace lldb;
20using namespace lldb_private;
21
22TypeCategoryImpl::TypeCategoryImpl(IFormatChangeListener* clist,
23                                   ConstString name) :
24m_value_nav(new ValueNavigator("format",clist)),
25m_regex_value_nav(new RegexValueNavigator("regex-format",clist)),
26m_summary_nav(new SummaryNavigator("summary",clist)),
27m_regex_summary_nav(new RegexSummaryNavigator("regex-summary",clist)),
28m_filter_nav(new FilterNavigator("filter",clist)),
29m_regex_filter_nav(new RegexFilterNavigator("regex-filter",clist)),
30#ifndef LLDB_DISABLE_PYTHON
31m_synth_nav(new SynthNavigator("synth",clist)),
32m_regex_synth_nav(new RegexSynthNavigator("regex-synth",clist)),
33#endif
34m_enabled(false),
35m_change_listener(clist),
36m_mutex(Mutex::eMutexTypeRecursive),
37m_name(name)
38{}
39
40bool
41TypeCategoryImpl::Get (ValueObject& valobj,
42                       const FormattersMatchVector& candidates,
43                       lldb::TypeFormatImplSP& entry,
44                       uint32_t* reason)
45{
46    if (!IsEnabled())
47        return false;
48    if (GetValueNavigator()->Get(candidates, entry, reason))
49        return true;
50    bool regex = GetRegexValueNavigator()->Get(candidates, entry, reason);
51    if (regex && reason)
52        *reason |= lldb_private::eFormatterChoiceCriterionRegularExpressionSummary;
53    return regex;
54}
55
56bool
57TypeCategoryImpl::Get (ValueObject& valobj,
58                       const FormattersMatchVector& candidates,
59                       lldb::TypeSummaryImplSP& entry,
60                       uint32_t* reason)
61{
62    if (!IsEnabled())
63        return false;
64    if (GetSummaryNavigator()->Get(candidates, entry, reason))
65        return true;
66    bool regex = GetRegexSummaryNavigator()->Get(candidates, entry, reason);
67    if (regex && reason)
68        *reason |= lldb_private::eFormatterChoiceCriterionRegularExpressionSummary;
69    return regex;
70}
71
72bool
73TypeCategoryImpl::Get (ValueObject& valobj,
74                       const FormattersMatchVector& candidates,
75                       lldb::SyntheticChildrenSP& entry,
76                       uint32_t* reason)
77{
78    if (!IsEnabled())
79        return false;
80    TypeFilterImpl::SharedPointer filter_sp;
81    uint32_t reason_filter = 0;
82    bool regex_filter = false;
83    // first find both Filter and Synth, and then check which is most recent
84
85    if (!GetFilterNavigator()->Get(candidates, filter_sp, &reason_filter))
86        regex_filter = GetRegexFilterNavigator()->Get (candidates, filter_sp, &reason_filter);
87
88#ifndef LLDB_DISABLE_PYTHON
89    bool regex_synth = false;
90    uint32_t reason_synth = 0;
91    bool pick_synth = false;
92    ScriptedSyntheticChildren::SharedPointer synth;
93    if (!GetSyntheticNavigator()->Get(candidates, synth, &reason_synth))
94        regex_synth = GetRegexSyntheticNavigator()->Get (candidates, synth, &reason_synth);
95    if (!filter_sp.get() && !synth.get())
96        return false;
97    else if (!filter_sp.get() && synth.get())
98        pick_synth = true;
99
100    else if (filter_sp.get() && !synth.get())
101        pick_synth = false;
102
103    else /*if (filter_sp.get() && synth.get())*/
104    {
105        if (filter_sp->GetRevision() > synth->GetRevision())
106            pick_synth = false;
107        else
108            pick_synth = true;
109    }
110    if (pick_synth)
111    {
112        if (regex_synth && reason)
113            *reason |= lldb_private::eFormatterChoiceCriterionRegularExpressionFilter;
114        entry = synth;
115        return true;
116    }
117    else
118    {
119        if (regex_filter && reason)
120            *reason |= lldb_private::eFormatterChoiceCriterionRegularExpressionFilter;
121        entry = filter_sp;
122        return true;
123    }
124
125#else
126    if (filter_sp)
127    {
128        entry = filter_sp;
129        return true;
130    }
131#endif
132
133    return false;
134}
135
136void
137TypeCategoryImpl::Clear (FormatCategoryItems items)
138{
139    if ( (items & eFormatCategoryItemValue)  == eFormatCategoryItemValue )
140        m_value_nav->Clear();
141    if ( (items & eFormatCategoryItemRegexValue) == eFormatCategoryItemRegexValue )
142        m_regex_value_nav->Clear();
143
144    if ( (items & eFormatCategoryItemSummary) == eFormatCategoryItemSummary )
145        m_summary_nav->Clear();
146    if ( (items & eFormatCategoryItemRegexSummary) == eFormatCategoryItemRegexSummary )
147        m_regex_summary_nav->Clear();
148
149    if ( (items & eFormatCategoryItemFilter)  == eFormatCategoryItemFilter )
150        m_filter_nav->Clear();
151    if ( (items & eFormatCategoryItemRegexFilter) == eFormatCategoryItemRegexFilter )
152        m_regex_filter_nav->Clear();
153
154#ifndef LLDB_DISABLE_PYTHON
155    if ( (items & eFormatCategoryItemSynth)  == eFormatCategoryItemSynth )
156        m_synth_nav->Clear();
157    if ( (items & eFormatCategoryItemRegexSynth) == eFormatCategoryItemRegexSynth )
158        m_regex_synth_nav->Clear();
159#endif
160}
161
162bool
163TypeCategoryImpl::Delete (ConstString name,
164                          FormatCategoryItems items)
165{
166    bool success = false;
167
168    if ( (items & eFormatCategoryItemValue)  == eFormatCategoryItemValue )
169        success = m_value_nav->Delete(name) || success;
170    if ( (items & eFormatCategoryItemRegexValue) == eFormatCategoryItemRegexValue )
171        success = m_regex_value_nav->Delete(name) || success;
172
173    if ( (items & eFormatCategoryItemSummary) == eFormatCategoryItemSummary )
174        success = m_summary_nav->Delete(name) || success;
175    if ( (items & eFormatCategoryItemRegexSummary) == eFormatCategoryItemRegexSummary )
176        success = m_regex_summary_nav->Delete(name) || success;
177
178    if ( (items & eFormatCategoryItemFilter)  == eFormatCategoryItemFilter )
179        success = m_filter_nav->Delete(name) || success;
180    if ( (items & eFormatCategoryItemRegexFilter) == eFormatCategoryItemRegexFilter )
181        success = m_regex_filter_nav->Delete(name) || success;
182
183#ifndef LLDB_DISABLE_PYTHON
184    if ( (items & eFormatCategoryItemSynth)  == eFormatCategoryItemSynth )
185        success = m_synth_nav->Delete(name) || success;
186    if ( (items & eFormatCategoryItemRegexSynth) == eFormatCategoryItemRegexSynth )
187        success = m_regex_synth_nav->Delete(name) || success;
188#endif
189    return success;
190}
191
192uint32_t
193TypeCategoryImpl::GetCount (FormatCategoryItems items)
194{
195    uint32_t count = 0;
196
197    if ( (items & eFormatCategoryItemValue) == eFormatCategoryItemValue )
198        count += m_value_nav->GetCount();
199    if ( (items & eFormatCategoryItemRegexValue) == eFormatCategoryItemRegexValue )
200        count += m_regex_value_nav->GetCount();
201
202    if ( (items & eFormatCategoryItemSummary) == eFormatCategoryItemSummary )
203        count += m_summary_nav->GetCount();
204    if ( (items & eFormatCategoryItemRegexSummary) == eFormatCategoryItemRegexSummary )
205        count += m_regex_summary_nav->GetCount();
206
207    if ( (items & eFormatCategoryItemFilter)  == eFormatCategoryItemFilter )
208        count += m_filter_nav->GetCount();
209    if ( (items & eFormatCategoryItemRegexFilter) == eFormatCategoryItemRegexFilter )
210        count += m_regex_filter_nav->GetCount();
211
212#ifndef LLDB_DISABLE_PYTHON
213    if ( (items & eFormatCategoryItemSynth)  == eFormatCategoryItemSynth )
214        count += m_synth_nav->GetCount();
215    if ( (items & eFormatCategoryItemRegexSynth) == eFormatCategoryItemRegexSynth )
216        count += m_regex_synth_nav->GetCount();
217#endif
218    return count;
219}
220
221bool
222TypeCategoryImpl::AnyMatches(ConstString type_name,
223                             FormatCategoryItems items,
224                             bool only_enabled,
225                             const char** matching_category,
226                             FormatCategoryItems* matching_type)
227{
228    if (!IsEnabled() && only_enabled)
229        return false;
230
231    lldb::TypeFormatImplSP format_sp;
232    lldb::TypeSummaryImplSP summary_sp;
233    TypeFilterImpl::SharedPointer filter_sp;
234#ifndef LLDB_DISABLE_PYTHON
235    ScriptedSyntheticChildren::SharedPointer synth_sp;
236#endif
237
238    if ( (items & eFormatCategoryItemValue) == eFormatCategoryItemValue )
239    {
240        if (m_value_nav->Get(type_name, format_sp))
241        {
242            if (matching_category)
243                *matching_category = m_name.GetCString();
244            if (matching_type)
245                *matching_type = eFormatCategoryItemValue;
246            return true;
247        }
248    }
249    if ( (items & eFormatCategoryItemRegexValue) == eFormatCategoryItemRegexValue )
250    {
251        if (m_regex_value_nav->Get(type_name, format_sp))
252        {
253            if (matching_category)
254                *matching_category = m_name.GetCString();
255            if (matching_type)
256                *matching_type = eFormatCategoryItemRegexValue;
257            return true;
258        }
259    }
260
261    if ( (items & eFormatCategoryItemSummary) == eFormatCategoryItemSummary )
262    {
263        if (m_summary_nav->Get(type_name, summary_sp))
264        {
265            if (matching_category)
266                *matching_category = m_name.GetCString();
267            if (matching_type)
268                *matching_type = eFormatCategoryItemSummary;
269            return true;
270        }
271    }
272    if ( (items & eFormatCategoryItemRegexSummary) == eFormatCategoryItemRegexSummary )
273    {
274        if (m_regex_summary_nav->Get(type_name, summary_sp))
275        {
276            if (matching_category)
277                *matching_category = m_name.GetCString();
278            if (matching_type)
279                *matching_type = eFormatCategoryItemRegexSummary;
280            return true;
281        }
282    }
283
284    if ( (items & eFormatCategoryItemFilter)  == eFormatCategoryItemFilter )
285    {
286        if (m_filter_nav->Get(type_name, filter_sp))
287        {
288            if (matching_category)
289                *matching_category = m_name.GetCString();
290            if (matching_type)
291                *matching_type = eFormatCategoryItemFilter;
292            return true;
293        }
294    }
295    if ( (items & eFormatCategoryItemRegexFilter) == eFormatCategoryItemRegexFilter )
296    {
297        if (m_regex_filter_nav->Get(type_name, filter_sp))
298        {
299            if (matching_category)
300                *matching_category = m_name.GetCString();
301            if (matching_type)
302                *matching_type = eFormatCategoryItemRegexFilter;
303            return true;
304        }
305    }
306
307#ifndef LLDB_DISABLE_PYTHON
308    if ( (items & eFormatCategoryItemSynth)  == eFormatCategoryItemSynth )
309    {
310        if (m_synth_nav->Get(type_name, synth_sp))
311        {
312            if (matching_category)
313                *matching_category = m_name.GetCString();
314            if (matching_type)
315                *matching_type = eFormatCategoryItemSynth;
316            return true;
317        }
318    }
319    if ( (items & eFormatCategoryItemRegexSynth) == eFormatCategoryItemRegexSynth )
320    {
321        if (m_regex_synth_nav->Get(type_name, synth_sp))
322        {
323            if (matching_category)
324                *matching_category = m_name.GetCString();
325            if (matching_type)
326                *matching_type = eFormatCategoryItemRegexSynth;
327            return true;
328        }
329    }
330#endif
331    return false;
332}
333
334TypeCategoryImpl::ValueNavigator::MapValueType
335TypeCategoryImpl::GetFormatForType (lldb::TypeNameSpecifierImplSP type_sp)
336{
337    ValueNavigator::MapValueType retval;
338
339    if (type_sp)
340    {
341        if (type_sp->IsRegex())
342            m_regex_value_nav->GetExact(ConstString(type_sp->GetName()),retval);
343        else
344            m_value_nav->GetExact(ConstString(type_sp->GetName()),retval);
345    }
346
347    return retval;
348}
349
350TypeCategoryImpl::SummaryNavigator::MapValueType
351TypeCategoryImpl::GetSummaryForType (lldb::TypeNameSpecifierImplSP type_sp)
352{
353    SummaryNavigator::MapValueType retval;
354
355    if (type_sp)
356    {
357        if (type_sp->IsRegex())
358            m_regex_summary_nav->GetExact(ConstString(type_sp->GetName()),retval);
359        else
360            m_summary_nav->GetExact(ConstString(type_sp->GetName()),retval);
361    }
362
363    return retval;
364}
365
366TypeCategoryImpl::FilterNavigator::MapValueType
367TypeCategoryImpl::GetFilterForType (lldb::TypeNameSpecifierImplSP type_sp)
368{
369    FilterNavigator::MapValueType retval;
370
371    if (type_sp)
372    {
373        if (type_sp->IsRegex())
374            m_regex_filter_nav->GetExact(ConstString(type_sp->GetName()),retval);
375        else
376            m_filter_nav->GetExact(ConstString(type_sp->GetName()),retval);
377    }
378
379    return retval;
380}
381
382#ifndef LLDB_DISABLE_PYTHON
383TypeCategoryImpl::SynthNavigator::MapValueType
384TypeCategoryImpl::GetSyntheticForType (lldb::TypeNameSpecifierImplSP type_sp)
385{
386    SynthNavigator::MapValueType retval;
387
388    if (type_sp)
389    {
390        if (type_sp->IsRegex())
391            m_regex_synth_nav->GetExact(ConstString(type_sp->GetName()),retval);
392        else
393            m_synth_nav->GetExact(ConstString(type_sp->GetName()),retval);
394    }
395
396    return retval;
397}
398#endif
399
400lldb::TypeNameSpecifierImplSP
401TypeCategoryImpl::GetTypeNameSpecifierForSummaryAtIndex (size_t index)
402{
403    if (index < m_summary_nav->GetCount())
404        return m_summary_nav->GetTypeNameSpecifierAtIndex(index);
405    else
406        return m_regex_summary_nav->GetTypeNameSpecifierAtIndex(index-m_summary_nav->GetCount());
407}
408
409TypeCategoryImpl::ValueNavigator::MapValueType
410TypeCategoryImpl::GetFormatAtIndex (size_t index)
411{
412    if (index < m_value_nav->GetCount())
413        return m_value_nav->GetAtIndex(index);
414    else
415        return m_regex_value_nav->GetAtIndex(index-m_value_nav->GetCount());
416}
417
418TypeCategoryImpl::SummaryNavigator::MapValueType
419TypeCategoryImpl::GetSummaryAtIndex (size_t index)
420{
421    if (index < m_summary_nav->GetCount())
422        return m_summary_nav->GetAtIndex(index);
423    else
424        return m_regex_summary_nav->GetAtIndex(index-m_summary_nav->GetCount());
425}
426
427TypeCategoryImpl::FilterNavigator::MapValueType
428TypeCategoryImpl::GetFilterAtIndex (size_t index)
429{
430    if (index < m_filter_nav->GetCount())
431        return m_filter_nav->GetAtIndex(index);
432    else
433        return m_regex_filter_nav->GetAtIndex(index-m_filter_nav->GetCount());
434}
435
436lldb::TypeNameSpecifierImplSP
437TypeCategoryImpl::GetTypeNameSpecifierForFormatAtIndex (size_t index)
438{
439    if (index < m_value_nav->GetCount())
440        return m_value_nav->GetTypeNameSpecifierAtIndex(index);
441    else
442        return m_regex_value_nav->GetTypeNameSpecifierAtIndex(index-m_value_nav->GetCount());
443}
444
445lldb::TypeNameSpecifierImplSP
446TypeCategoryImpl::GetTypeNameSpecifierForFilterAtIndex (size_t index)
447{
448    if (index < m_filter_nav->GetCount())
449        return m_filter_nav->GetTypeNameSpecifierAtIndex(index);
450    else
451        return m_regex_filter_nav->GetTypeNameSpecifierAtIndex(index-m_filter_nav->GetCount());
452}
453
454#ifndef LLDB_DISABLE_PYTHON
455TypeCategoryImpl::SynthNavigator::MapValueType
456TypeCategoryImpl::GetSyntheticAtIndex (size_t index)
457{
458    if (index < m_synth_nav->GetCount())
459        return m_synth_nav->GetAtIndex(index);
460    else
461        return m_regex_synth_nav->GetAtIndex(index-m_synth_nav->GetCount());
462}
463
464lldb::TypeNameSpecifierImplSP
465TypeCategoryImpl::GetTypeNameSpecifierForSyntheticAtIndex (size_t index)
466{
467    if (index < m_synth_nav->GetCount())
468        return m_synth_nav->GetTypeNameSpecifierAtIndex(index);
469    else
470        return m_regex_synth_nav->GetTypeNameSpecifierAtIndex(index - m_synth_nav->GetCount());
471}
472#endif
473
474void
475TypeCategoryImpl::Enable (bool value, uint32_t position)
476{
477    Mutex::Locker locker(m_mutex);
478    m_enabled = value;
479    m_enabled_position = position;
480    if (m_change_listener)
481        m_change_listener->Changed();
482}
483